Variable defined in scope gives error depending on scope

I think it's called "stack frames" (but I may be wrong) ..the data to support automatic allocation and destruction. And there's a reason why it's been around for so long (and why it's so limited).
  • #1
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
  • #2
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.)
 
  • #3
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?
 
  • #4
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 Grelbr42 and Filip Larsen
  • #5
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 Grelbr42 and (deleted member)
  • #6
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.
 
  • #7
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 FactChecker
  • #8
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 Vanadium 50
  • #9
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 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 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?
 

FAQ: Variable defined in scope gives error depending on scope

Why does a variable defined in a specific scope give an error when accessed outside of that scope?

Variables declared within a certain scope, such as a function or a block of code, are only accessible within that scope. Trying to access a variable outside of its defined scope will result in an error because the variable is not recognized in that context.

How can I avoid errors related to variable scope in my code?

To prevent scope-related errors, make sure to declare variables in the appropriate scope where they will be used. Avoid using global variables unless absolutely necessary, as they can lead to confusion and unintended consequences.

Can a variable defined in a higher scope be accessed in a lower scope?

Yes, variables defined in a higher scope, such as a global variable, can be accessed in a lower scope, such as within a function. However, the reverse is not true - variables defined in a lower scope cannot be accessed in a higher scope.

What is the difference between local and global variables in terms of scope?

Local variables are declared within a specific scope, such as a function, and can only be accessed within that scope. Global variables, on the other hand, are declared outside of any specific scope and can be accessed from anywhere in the code.

How can I troubleshoot errors related to variable scope in my code?

To troubleshoot scope-related errors, carefully review where variables are declared and where they are being accessed. Use console.log statements or debugging tools to track the flow of your code and identify any scope-related issues that may be causing errors.

Similar threads

Replies
22
Views
3K
Replies
8
Views
2K
Replies
6
Views
10K
Replies
1
Views
1K
Replies
10
Views
2K
Replies
13
Views
2K
Replies
1
Views
1K
Back
Top