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 = newint(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.
"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.
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.
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!
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.)
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()
{
staticint 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.
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.
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.