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

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.

Related

C++ returned array loses it's values depending on if any new array is declared or not. Its losing it if yes [duplicate]

This question already has answers here:
Returning an array using C
(8 answers)
Closed 6 months ago.
I wrote a simple c++ program where i am getting a simple float Array from a function. Then I call a function where the generated Array is a parameter of. I print the first value of the Array through the function. It works! BUT when i am declaring another array in the function before i print the value from the first array, the printed value is not the expected one. MAGIC!
CODE THAT DOESN'T WORK:
#include <iostream>;
float* getArray() {
float Array[] = { 4 };
return Array;
}
void compute(float* Array) {
bool newArray[1];
float content = Array[0]; //breakpoint: content will be -107374176.
std::cout << content;
}
int main() {
float* Array = getArray();
compute(Array);
}
OUTPUT: -1.07374e+08
When removing the line "bool newArray[1];" (line 10) the code starts to work.
OUTPUT: 4
Test it your self! Can someone explain me why this happens?
Your main function has a bug. It passes a pointer to Array to compute, which dereferences it. But Array is out of scope at this point since its scope ends when getArray ends. So you are trying to access an object that no longer exists. That is undefined behavior and produces completely unpredictable results.
Arguably, getArray also has a bug since it always returns a pointer to an object that no longer exists. So there is no way to use it. Whether or not that's a bug depends on what the caller is supposed to be able to do with the returned value which cannot be determined due to the lack of comments.

C++ reference bug [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 4 years ago.
I tried to understand how c++ references work and I tried to write the next code:
#include <iostream>
int& func();
int main()
{
std::cout <<func()<< std::endl;
system("pause");
return 0;
}
int& func()
{
int x = 23;
return x;
}
for my understanding, the int x which was initialized in the function will be erased after the func ends and then the value that the function is returning will point to something that doesn`t exist.
But when I print it I get 23 in the console.
How does it possible?
The value is written in the memory inside func(), but you are wrong in "doesn't exist" after return.
Why would it not exist, did anything else overwrite that memory? You can't be sure. It's undefined behavior.
You are just returning a memory adress from func() which after return is made available for other variables. But if that (now available) memory adress is not overwriten, it will hold the value 23.. Until the end of days ;)
Here's #George 's reference to undefined behavior :
https://en.cppreference.com/w/cpp/language/ub
Furthermore your code might have some errors... Anyway, look at this and it shall solve your worries
Can a local variable's memory be accessed outside its scope?

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

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.

C++ scopes and allocation [duplicate]

This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Closed 6 years ago.
If I understand correctly, variables that are not dynamically allocated are supposed to be deleted at the end of their scope.
However, I wanted to try it out with this code (which I think is not correct as I am supposed to use dynamic allocation) :
int* function()
{
int a = 3;
return &a;
}
int main(int argc, char const *argv[]) {
int* a(function());
std::cout << *a << std::endl; // prints 3
}
Why can I still access the value of the variable a by using the pointer returned by the function when it is supposed not to exist anymore ?
a and hence the return value from function has gone out of scope. You are just lucky.
Just be careful and compile with all the warnings enables - and take heed of those warnings.
The fact that you can access the value is pure luck. The code has undefined behaviour (since the variable is destroyed) and the compiler can generate whatever it wants - but you cannot rely on it.

c++ dangerous pointers practice? [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 9 years ago.
#include <stdio.h>
int *pPointer;
void SomeFunction()
{
int nNumber;
nNumber = 25;
// make pPointer point to nNumber:
pPointer = &nNumber;
}
void main()
{
SomeFunction(); // make pPointer point to something
cout<< "Value of *pPointer: "<< *pPointer <<endl;
}
I have been told that using pointers like this is dangerous, could anyone please explain why it is dangerous and what would be the 'safe' way to write that piece of code?
will 25 always be printed out to the screen in that way? if not then why?
Using a pointer to local variable outside of the scope of the variable is always dangerous. It invokes undefined behavior.
Unsafe, because its value may be overwritten
Safe way: just
int SomeFunction()
{
int nNumber;
nNumber = 25;
return nNumber;
}
Will do fine. If your return value is large, return value optimization will save your life anyway.
25 printed? Implementation specified. Most likely not because you are in a new stack frame when the function returned.
You are talkin about wild pointers which termed to be dangerous to use because a pointer, is a memory address, and in modern computers memory is protected (only allowed to be accessed by the program that owns it)
an attempt to read or write to memorry address 0 or NULL will cause your program to crash with a memory violation error.
he best way to protect againsed this to initalise a pointer as soon as it is created.
anouther way, is to test the pointer before using it.
if (pointer == 0) {
cout << "WARNING... cant use this pointer";
}
else {
// it is okay to use this pointer
}