How does C++ proceed for += with a variable without value? [duplicate] - c++

This question already has answers here:
What happens when I print an uninitialized variable in C++? [duplicate]
(4 answers)
Closed 6 years ago.
i am currently learning C++ and i had a question about some "weird" things i noticed while testing what i have learnt.
So i use this :
int marc[9];
int sum = 0;
for (int x =0; x < 9; x++) {
marc[x] = x*4;
sum += marc[x];
}
cout << sum << endl;
And i get a normal result which is 144
However, if i changed
int sum = 0;
to
int sum;
I got a crazy result like 19557555002
So i was wondering what is happening in the second case?
Thanks for your answer :)

You are operating on uninitialized memory in the second case. Non-static local variables are not initialized to zero by the runtime like in other languages, if you need sum to have a defined value, you must initialize it yourself. The 19557555002 will be the integer interpretation of any bytes that were present at the memory address allocated for sum.
Further reading: What happens to a declared, uninitialized variable in C? Does it have a value?

Its called an undefined behavior and it happens when you don't initialize your variables.
int sum;
above code can only declare a variable but it doesn't initialize it by default so the variable contains a garbage value.

this creates an uninitialized int int sum;
it can have "garbage" values, and this is exactly what happened to you
how this happens: let's say you use an int x in address y, and sets it to 19557555002. now, lets say you "leave" that address (go out of scope, program terminates, OS takes that memory...) and someone else takes it because he wants to put there a new int. if he just declares his int, without initializing it, his int can be stationed (if the OS so desires...) in address y, that previously used to hold your int, which means in address y, he will find 19557555002. That is what could happen to you if you don't initialize variables.

Memory for local variables is typically allocated on the stack. This means that without some initialization, they will hold some data that was residing there previously.
As others said it is undefined behavior, but practically, on most implementations, it results in effects like this:
void foo()
{
int a = 5;
}
void bar()
{
int b;
std::cout << b;
}
void someCaller()
{
foo();
bar();
}
On most implementations, this will usually result in the printing of 5 on the stdout.
Note that some compilers like MSVC initialize all variables in Debug configuration, but usually any kind of optimization flags will avoid initializing memory, if not explicitly requested.

Related

C++: Incoherent deletion from the Stack? [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 5 years ago.
I'm trying to understand how to use functions in C++ to return arrays. I want to understand what's going on here. This is my code, that I compile with g++ -Wall return_array.cpp -o return_array
#include <iostream>
int * do_something(int number){
int viz[3] = {1,2,3};
viz[2] += number;
return &viz[0];
}
int main(){
int *viz;
viz = do_something(3);
std::cout << viz[2] << "\n";
return 0;
}
which gave me the following error:
return_array.cpp: In function ‘int* do_something(int)’:
return_array.cpp:4:6: warning: address of local variable ‘viz’ returned [-Wreturn-local-addr]
int viz[3] = {1,2,3};
By my research, the error is due to the fact that I'm trying to access a pointer that has been deleted from the Stack once I leave the function's scope. However, if I run the code with a workaround:
int * do_something(int number){
int viz[3] = {1,2,3};
int *pointer;
viz[2] += number;
pointer = &viz[0];
return pointer;
}
it compiles and runs just fine. Isn't this new pointer in the precise same situation? Once I leave the function, it is out of scope and should be deleted from the Stack, by the same argument as before. What am I missing?
EDIT:
My question here is not whether or not returning the pointer to a local array produces an error. It should and it does. The question is why the pointer that has been assigned to the pointer to the same array does not!
Once control leaves the function, the array is out of scope. It might be erased, it might not. That region of memory might still contain those numbers for a while, and it might not. Trying to read it might work, or it might do anything. This is known as undefined behavior, and it is a difficult thing to detect and a good thing to avoid.

Return value in C++ [duplicate]

This question already has answers here:
C++ return value without return statement
(6 answers)
Closed 6 years ago.
I am confused with the following output in C++
int add()
{
int c = 2+3;
}
int main()
{
int x = add();
cout << x;
return 0;
}
This prints 5.even if we do not write return statement.
How this is managed in C++.
Please help.
This is UB. You're right to be confused - this can work one day and fail the next. Don't rely on undefined behavior.
If you want to know why it works, it's because parameters & return values are passed on a data structure called stack (well - usually; sometimes passed in the same register). Similarly, most implementations use this same stack for locals. Therefore, the int in add will be located in the same place as where the return value is expected (by your specific implementation) and your implementation doesn't invalidate memory when your int there is destructed. But it's still destructed, it's still UB and it might break in any second.
As the comments wrote, you might turn on warnings to avoid this kind of error.

stack variable lifetime curious example [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
Please consider this simple example:
#include <iostream>
const int CALLS_N = 3;
int * hackPointer;
void test()
{
static int callCounter = 0;
int local = callCounter++;
hackPointer = &local;
}
int main()
{
for(int i = 0; i < CALLS_N; i++)
{
test();
std::cout << *hackPointer << "(" << hackPointer << ")";
std::cout << *hackPointer << "(" << hackPointer << ")";
std::cout << std::endl;
}
}
The output (VS2010, MinGW without optimization) has the same structure:
0(X) Y(X)
1(X) Y(X)
2(X) Y(X)
...
[CALLS_N](X) Y(X)
where X - some address in memory, Y - some rubbish number.
What is done here is the case of undefined behaviour. However I want to understand why there is such behaviour in current conditions (and it is rather stable for two compilers).
It seems that after test() call first read of hackPointer leads to valid memory, but second successive instant read of it leads to rubbish. Also on any call address of local is the same. I always thought that memory for stack variable is allocated on every function call and is released after return but I can't explain output of the program from this point of view.
"Releasing" automatic storage doesn't make the memory go away, or change the pattern of bits stored there. It just makes it available for reuse, and causes undefined behaviour if you try to access the object that used to be there.
Immediately after returning from the function, the memory occupied by the local probably hasn't been overwritten, so reading it will probably give the value that was assigned within the function.
After calling another function (in this case, operator<<()), the memory is likely to have been reused for a variable within that function, so probably has a different value.
You are quite right that this is undefined behaviour.
That aside, what's happening is that std::cout << *hackPointer involves a function call: operator<<() gets called after the value of *hackPointer has been read. In all likelihood, operator<<() uses its own local variables that end up on the stack where local was, wiping out the latter.

Order of Local Variables : Best way to declare variables(varying in size) in cpp [duplicate]

This question already has answers here:
How declaration of variables behave?
(2 answers)
Closed 9 years ago.
I'm currently reviewing a code, and there are many local variables in varying sizes.
Is declaring in increasing order of size the preferable one or vice versa.
Explain it with memory layout in either of scenarios.
Is memory allocated for the local variables based on order of declaration or on size.
int fun()
{
struct *ptr;
int var1;
long double *ld;
.
.
.
.
}
The best place to declare (and initialize) a local variable in C++ is right at the point where it's first needed.
The size of the variable should not be a consideration at all, unless you have specific evidence to the contrary.
Compiler will reorder local variables as it sees fit, when it does optimizing. In short, order of variables in the same scope does not matter.
What is good idea though, is to declare local variables in the scope where it is used, for example:
void func() {
//int i, j; // not here!
for (int i = 0 ; i<10; ++i) {
int j = func2(i);
...
}
// i and j below are different variables than i and j above
// you can consider changing their names if they also have different meaning
for (int i = 0 ; i<10; ++i) {
int j = func3(i);
...
}
}
Though for good optimizing compiler, that likely will not matter from performance or memory footprint point of view (it will detect when variables are used anyway). It will still make the code more readable, and avoid mixing unrelated values in different scopes, thus protecting from some stupid bugs not caught by compiler warnings (because compiler doesn't know when you are accidentally forgetting re-initialization of re-used variable, but it will know if you forget to initialize a new variable).
Also, important thing when worrying about variables (or anything): remember to turn on warnings for compiler, like -Wall -Wextra for gcc. Also, using valgrind is good idea (if you can get your code to run on OS which has valgrind).
My approach is, that I declare local variables in the smallest possible scope, at the scope's beginning, e.g.
void foo()
{
int local1 = 42;
int local2 = bar(local1);
if ( local2 != local1)
{
double local3 = double(local2)/double(local1);
MyMemoryAllocatingObject mmao; // large memory allocation, deallocation in destructor
baz(local3);
bat(mmao);
} // mmao memory gets freed here
}
For not-sophisticated compilers it helps optimization, for users it helps tracking the information. Plus, it helps keeping memory footprint as small as possible, because the locals go out of scope (sic!), i.e. their destructor is called.

Returning reference of local variables in C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ Returning reference to local variable
Can a local variable’s memory be accessed outside its scope?
In the following code
int& h() {
int o=100;
return o;
}
int main() {
int t=h(); //line 1
cout<<t; //line 2
return 0;
}
Why the output is coming as 100 i.e. the value of the local variable of the function and why there is no error in line 1 because the return type of function is int& but we are returning its return value to a int.
You should never return a reference or a pointer to a local variable. It will be destroyed right when the function returns. It may appear to work in some cases because the stack may not yet be overwritten. But it will fail unexpectedly eventually.
It is legal to assign a reference to something to a value of the same type. So in your assignment a copy is made.
The value is 100 because the memory containing it has just been freed and nobody has written anything to it. Here's another example:
int& h() {
int o=100;
return o;
}
int& h2()
{
int o = 10;
return o;
}
int main() {
int t=h() + h2(); //line 1
cout << t;
return 0;
}
If you compile this with no optimization on Visual Studio, the result will be 20 and here's what will happen:
h() gets called, writes 100 to memory, frees it and returns a reference.
h2() gets called and writes 10 to the same place in memory (it has been freed before)
main() computes the sum of 2 values from the same place in memory. Thus, it's 10+10.
Setting int from int & is not an error. It's a valid operation that means "take this reference to some object and copy whatever is there to my local variable".
Return reference local variable - for single thread application /example by Ivan/ is not problem. For multithread application is problem - when diferent threads use function e.g. h(). In this case may be moments, when threads cross used unallocate memory.
Compilers don't necessarily protect against bad and/or undefined behavior.
Check what options you're passing to your compiler.
Compiling your code at codepad.org produces a warning: http://codepad.org/ParI4AOG
In function 'int& h()':
Line 6: warning: reference to local variable 'o' returned