Tutorials on Memory are Lacking

Pages: 123
Your tutorials on memory management are lacking a lot of critical information. For starters, you mention how the heap works but you never talk about the stack. Here is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
int* foo() {
    int i = 3;
    return &i; 
}
void bar() {
    int k = 8;
}

int main(int argc, char ** args) {
    int *i = foo();
    bar();
    std::cout << *i ;
}


The code above prints 8 to the console, not 3. That is because the foo method wrote the int i to the stack, which was overwritten by the bar method. The compiler gives you a warning about this. I'm not asking why this is happening, I'm asking why it was never mentioned in your tutorials?

I would expect your tutorials to say something like "you should never return a local variable from a method unless it came from the heap (was created using the new keyword)" but you never mentioned that. For example, I could easily modify the problem to work:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int* foo() {
    int * i = new int(3);
    return i; 
}
void bar() {
    int k = 8;
}

int main(int argc, char ** args) {
    int *i = foo();
    bar();
    std::cout << *i ;
    // don't forget to delete it!!!
}


and now it prints 3 instead, but since I used the 'new' keyword, I must also remember to delete that pointer.

Would somebody please update the tutorial on dynamic memory? It should explain how the memory stack works, and why you should never return a local variable from a method.
Actually, returning the address of a local variable is undefined behavior. That's really all you need to know, especially since doing otherwise provide no advantages.

The tutorials aren't comprehensive. They can't be, given the size and how detailed the standard is. It's not a beginners language.
returning the address of a local variable is undefined behavior.

The fact that it's undefined behaviour is exactly why you should warn people in the tutorials to not use it.

The tutorials aren't comprehensive.

It's not like I'm talking about a piece of trivia that people will never need to know about, this is a vital piece of information that is bound to give people headaches if they don't know it. Anybody who programs in C or C++ will need to understand how this works.

It's not a beginners language.

I'm not sure if you mean it's not for first time programmers, or that it's just tough for anybody when they are learning it. I am not a first time programmer, I have been programming in other languages for years. If somebody came from a higher level language, they probably know nothing about the stack or heap, which is why it's critical for the C++ tutorials to discuss it.
The tutorial need only cover object lifetime and then this case is already covered.
"you should never return a local variable from a method unless it came from the heap (was created using the new keyword)" but you never mentioned that.
Maybe because this statement is false?
Maybe because this statement is false?

First, if you're going to say it's false then you should explain why it's false. I gave an example that you can try yourself and prove that it's dangerous, maybe on some architectures it is safe, but if it's not safe on some then using it means your code is not portable. Can you at least show me a counter example?

Second, if I'm getting it wrong, maybe it's because the tutorials don't explain it at all.
Last edited on
The tutorial need only cover object lifetime and then this case is already covered.


Right, as soon as the tutorial adds that section let me know.
msknapp84 wrote:
you should never return a local variable from a method unless it came from the heap
msknapp84 wrote:
if you're going to say it's false then you should explain why it's false.
1
2
3
4
5
int f()
{
    int x = 1;
    return x; //this is not dangerous
}
If only there was like, I don't know, some sort of contact form you could use to send messages directly to the admin instead of starting a thread for every problem you spot. Maybe like the one that already exists!

http://www.cplusplus.com/contact.do
Pretty much the only time you should be returning pointers is:

1: You're interfacing with a C library
2: You need heap memory (unknown size, and/or is going to be passed around a lot in the program)
3: You're writing a speed/memory-critical application
4: Your library doesn't support the STL
5: It's less elegant to use the STL

Other than that, references are a much safer alternative. The STL also provides classes such as std::vector and smart pointers. These replace most of the needs for raw pointers. (Note that I'm not telling you to use the STL for everything, which is why I stated the 5th reason.)
Why would you use the STL when you have the whole of the C++ Standard Library available to you?

http://stackoverflow.com/a/5205571/1959975
Also in no place C++ standard mentions that objects with automatic lifetime duration are stored on stack.

In fact only mention of stack aside from standard library one is in function call stack context (stack unwinding).

Saying that local variables are created on stack is like saying that there is always 8 bits in byte: you are unlikely to see something other, but generally it is false.

you should never return a local variable from a method unless it came from the heap
I think you wanted to say pointer or reference, but still...
1
2
3
4
5
int* safe()
{
    static int i = 42;
    return &i;
}
So in the end we just need to cover lifetime of object and mention that you should never use pointer or reference to objec which lifetime has expired.
Last edited on
I would agree with msknapp84. For clarity it should be mention that a pointer to a local variable shall never be returned. The lack of clarity is one of the most important sources of bugs...

MiiNiPaa wrote:
So in the end we just need to cover lifetime of object and mention that you should never use pointer or reference to objec which lifetime has expired.
It's rather unlikely that many people understand this.

NoXzema wrote:
It's not a beginners language.
So no one can program C++ because at one point everybody is a beginner.
Saying that local variables are created on stack is like saying that there is always 8 bits in byte: you are unlikely to see something other, but generally it is false.
The difference being that non-8-bit byte computers exist, while there appear to exist no stackless computers.
I don't see a problem with stating something that's false in theory but true in actuality, and which doesn't show any sign of changing any time soon.
It's rather unlikely that many people understand this.
It is better to link "local variables" with "storage duration". Like "local variable" == "automatic storage duration" == "destroyed when containing code block is closed (e.g. function returns)" == "All pointers to it is invalidated when it is out of scope" == "you should not return pointers to local variables because they are are invalid"
Just saying that you cannot return pointers/references to local variable is not enough. We need to say why they are invalidated

Ok, I was too pedantic. I actually fine with something like "objects with automatic storage duration like local variables are usually creted on stack" following with description what stack is.

while there appear to exist no stackless computers
Well, nothing forces us to use stack to store local variables. It is just most sane approach. It can use some memory pool, leaving stack only for argument passing and return addresses.
Local variables are often stored in registers instead of the stack.
It can use some memory pool, leaving stack only for argument passing and return addresses.
Yeah, sure. But is it actually done?

Local variables are often stored in registers instead of the stack.
That's not what is usually meant by "store".
Am I the only one that cares that OP's objection is only relevant because, as of now, stdcall happens to be the default calling convention? For that matter am I the only one that thinks that an introductory tutorial might be just a wee bit early to start introducing beginners to IDL\inter-operability? This isn't an issue in a cdecl call, nor is it a problem with a fastcall. The tutorial doesn't mention this stuff because the standard doesn't either, memory allocation is platform dependent consideration. You have to know what you are writing on, no amount of hand holding from us is going to get around that.
I don't see what the calling convention has to do with this.
In the C calling convention for instance arguments are passed on the stack and EAX is used to return addresses and integers:
- http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl

In a fastcall* (x64 and ARM), EAX is reserved for returning values:
- http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
- http://msdn.microsoft.com/en-us/library/6t169e9c.aspx
- http://msdn.microsoft.com/en-us/library/7572ztz4.aspx

Am I misreading anything here?

*: msfastcall is the only one that is well defined and as far as I can tell it was adopted by GCC at some point.
Last edited on
Pages: 123