Variable defined in scope gives error depending on scope

  • Context: C/C++ 
  • Thread starter Thread starter member 428835
  • Start date Start date
  • Tags Tags
    Error Scope Variable
Click For Summary

Discussion Overview

The discussion revolves around a C++ programming issue related to variable scope, memory allocation, and pointer management. Participants explore the implications of using nested scopes and the behavior of dynamically allocated memory with the `new` operator.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Conceptual clarification

Main Points Raised

  • Some participants note that the nested braces restrict the scope of the pointer variable `i`, making it undefined outside the inner block.
  • There is a suggestion that moving the declaration of `i` outside the nested braces would resolve the issue, allowing it to be accessed later.
  • One participant expresses confusion about the purpose of `new`, believing it ensures memory remains allocated without needing to delete it, prompting others to clarify the relationship between pointer scope and memory allocation.
  • Some participants emphasize the importance of pairing `new` with `delete` to avoid memory leaks and suggest that relying on scope rules is generally sufficient for managing memory.
  • There is a discussion about the convenience of `new/delete` versus stack allocation, with differing opinions on when dynamic memory management is appropriate.
  • A participant expresses frustration with perceived criticism and insists that their original post contained the minimum code necessary to illustrate the problem.
  • Another participant seeks clarification on what "fail" means in the context of the original code, asking for specifics about error messages or unexpected outputs.
  • One participant provides a detailed breakdown of the code's behavior, explaining how the pointer and variable allocations interact within their respective scopes.

Areas of Agreement / Disagreement

Participants generally agree on the importance of understanding variable scope and memory management, but there are competing views on the best practices for using `new` and `delete`, as well as the appropriateness of dynamic memory allocation in various contexts. The discussion remains unresolved regarding the optimal approach to managing memory in this scenario.

Contextual Notes

Some limitations include the potential for misunderstanding the implications of scope on variable lifetime and the nuances of memory management in C++. There are also unresolved aspects regarding the specific error messages encountered by the original poster.

member 428835
Hi PF!

The following runs if lines 5 and 11 are commented, but fails otherwise. Can someone explain what's happening here? Something with scope but I'm very lost. Thanks in advance!
C++:
#include <iostream>

int main()
{
    {
        int* i = new int;
        {
            int b = 5;
            i = &b;
        }
    }

    std::cout<< *i;
    return 0;
}
 
Technology news on Phys.org
Those {} brackets on lines 5 and 11 restrict the definition of "int* i = new int;" on line 6 to within that scope from 5 to 11. So *i is not defined on line 13.
You can also move line 6 to just beneath line 4 to increase the defined scope of *i to include the print statement on line 13. (In this case, that would make the nested {{ ...}} unnecessary, so you might just as well remove the lines that you mentioned.)
 
FactChecker said:
Those {} brackets on lines 5 and 11 restrict the definition of "int* i = new int;" on line 6 to within that scope from 5 to 11. So *i is not defined on line 13.
You can also move line 6 to just beneath line 4 to increase the defined scope of *i to include the print statement on line 13. (In this case, that would make the nested {{ ...}} unnecessary, so you might just as well remove the lines that you mentioned.)
Thanks. I thought the point of using "new" was to store on the heap, which I thought meant we had to manually allocate memory, so without deleting it was going to stay. Can you correct my misunderstanding?
 
1. The } means you told the compiler you didn't need the variable any more. Why are you surprised that it took you at your word?

2. Always always always pair news and deletes. Always. This will save you lots of time and trouble,

3. Multiple people have asked you multiple times to post the minimum code needed to demonstrate the problem. Had you done that, you would have discovered the problem with the braces. Maybe that would have pointed you at the problem, and maybe it wouldn't. But the idea that you want our help but don't want our advice i not going to get you where you want to go.

4. Do not count on anything implementation dependent, like what goes in what segments. In particular:
-- Do not count on the compiler preserving the value of a variable after you told it you don;t need it any more
-- Do not assume that the garbage collection will clean up after you when you are done with things

Tell the computer what you want it to do. Don't depend on it anticipating.
 
  • Like
Likes   Reactions: Grelbr42 and Filip Larsen
joshmccraney said:
I thought the point of using "new" was to store on the heap, which I thought meant we had to manually allocate memory, so without deleting it was going to stay.
You're confusing two different things.

The variable i in your code is not an int. It's a pointer to an int. It is only in scope inside the inner pair of braces. That's true regardless of how you assign the pointer.

The actual int variable is allocated by "new" and, since you did not include a corresponding "delete", it will either be automatically thrown away when your program exits, or become a memory leak, depending on the specific implementation. Assigning a pointer to that int to the pointer variable i, and what scope that pointer variable is visible in, has nothing whatever to do with any of that.
 
  • Like
Likes   Reactions: Grelbr42 and (deleted member)
joshmccraney said:
Thanks. I thought the point of using "new" was to store on the heap, which I thought meant we had to manually allocate memory, so without deleting it was going to stay. Can you correct my misunderstanding?
Trying to use "new" and "delete" to control how long memory is kept is making things much more complicated than they usually need to be. The usual scope rules are very good at automatically taking care of those things. You should use the scope rules in the methodical way they were intended until they are very natural for you.
 
FactChecker said:
Trying to use "new" and "delete" to control how long memory is kept is making things much more complicated than they usually need to be. T
For an int, I agre. And calling a non-integer variable "i" is also a dirty trick played on Future You.

But fort a big, complex object? I think new/delete is much more convenient taht malloc./sizeof/free. And if a problem with a big, complex object? also eppears when replaced by an int, it will help us figure out what is wrong.
 
  • Like
Likes   Reactions: FactChecker
Vanadium 50 said:
For an int, I agre. And calling a non-integer variable "i" is also a dirty trick played on Future You.

But fort a big, complex object? I think new/delete is much more convenient taht malloc./sizeof/free. And if a problem with a big, complex object? also eppears when replaced by an int, it will help us figure out what is wrong.
I agree that if customized memory management is needed, then it is nice.
Some situations where it is needed are where many (or an undetermined number of) objects need to be created and deleted during a single run in a single task. That is a key feature of Object Oriented Design (OOD).
My caution is that it should not be used when the simple scope rules suffice.
 
  • Like
Likes   Reactions: Vanadium 50
Vanadium 50 said:
But fort a big, complex object? I think new/delete is much more convenient taht malloc./sizeof/free.
But it's less convenient than just declaring the variable on the stack in the appropriate scope.
 
  • Like
Likes   Reactions: FactChecker
  • #10
PeterDonis said:
But it's less convenient than just declaring the variable on the stack in the appropriate scope.
And more treacherous.
 
  • #11
PeterDonis said:
than just declaring the variable on the stack
When you can/

An int? Sure. A variable number of objects of variable size? Not so easy. Ther'es a reason that the developers put in new/delete. I mean besides tripping up the unwary.
 
  • Like
Likes   Reactions: FactChecker
  • #12
Vanadium 50 said:
1. The } means you told the compiler you didn't need the variable any more. Why are you surprised that it took you at your word?

2. Always always always pair news and deletes. Always. This will save you lots of time and trouble,

3. Multiple people have asked you multiple times to post the minimum code needed to demonstrate the problem. Had you done that, you would have discovered the problem with the braces. Maybe that would have pointed you at the problem, and maybe it wouldn't. But the idea that you want our help but don't want our advice i not going to get you where you want to go.

4. Do not count on anything implementation dependent, like what goes in what segments. In particular:
-- Do not count on the compiler preserving the value of a variable after you told it you don;t need it any more
-- Do not assume that the garbage collection will clean up after you when you are done with things

Tell the computer what you want it to do. Don't depend on it anticipating.
dude i cant tell what you're talking about re comment 3. my OP WAS the min working code. i know there's an error, hence me saying "The following runs if lines 5 and 11 are commented, but fails otherwise". I literally spelled out what the issue was and how to get rid of it.

your constant berating is ridiculous. thanks to everyone, but after a decade im done with this site and will not recommend peers to it. thanks to all who have helped. so long pf!
 
  • #13
joshmccraney said:
The following runs if lines 5 and 11 are commented, but fails otherwise.
What does "fail" mean?

Did you get a compiler error message, or a run-time error message? If so, what?

Or did it compile and run without error messages, but produce unexpected output? If so, what output did you expect, and what did you actually get?
 
  • #14
Here's my understanding of what's happening with your code.

Line 6 allocates a pointer-to-int named i on the stack. The scope of i is lines 6 through 11. Line 6 also allocates an anonymous int on the heap, containing whatever "random" sequence of bits happened to be there already, and stores its address in i.

Line 8 allocates an int named b on the stack, and stores the value 5 in it.

Line 9 stores the address of b in i, overwriting the address of the anonymous int (from line 6), which is now inaccessible.

The closing brace in line 10 terminates the scope of the name b that was defined on line 8. You cannot use it past this point. What happens to the value 5 stored on the stack is undefined. It depends on the compiler and operating system. The value 5 might remain accessible via the pointer i, as *i, until its location is allocated to something else.

However...

The closing brace in line 11 terminates the scope of the name i that was defined on line 6. You cannot use it past this point.

Therefore I would expect line 13 to produce a compiler error message, something like "undefined name" or "undeclared variable". Is that what happened?
 

Similar threads

  • · Replies 22 ·
Replies
22
Views
4K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 1 ·
Replies
1
Views
1K
Replies
12
Views
3K
  • · Replies 10 ·
Replies
10
Views
3K
  • · Replies 13 ·
Replies
13
Views
3K
Replies
3
Views
1K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 6 ·
Replies
6
Views
12K
  • · Replies 15 ·
Replies
15
Views
4K