Deleting a pointer to an automatic variable [duplicate] - c++

This question already has an answer here:
What is the behavior of "delete" with stack objects? [duplicate]
(1 answer)
Closed 8 years ago.
Please look at this code
int i = 10; //line 1
int *p = &i; //line 2
delete p; //line 3
cout << "*p = " << *p << ", i = " << i << endl; //line 4
i = 20; //line 5
cout << "*p = " << *p << ", i = " << i << endl; //line 6
*p = 30; //line 7
cout << "*p = " << *p << ", i = " << i << endl; //line 8
What is the result of this code? Especially of line 3, 5 and 7? Do they invoke undefined behavior? What would be the output?
EDIT : I tried running it using g++, and it's compiling and running fine! I'm using MinGW on Windows 7.
What does Standard say in this context?

You can delete only a pointer if you have ever allocated it dynamically using new. In this case you have not allocated the pointer using new but simply defined and initialized it to point to a local variable of type int.
Invoking delete on a pointer not allocated dynamically using new is something called Undefined Behavior. In short, it means that anything on the earth can happen when such a code is executed and you can't complaint a bit to anyone on this planet.

delete p; is UB and so any further behavior can't be predicted or relied upon. You program might crash immediately or spend all your money or just exit from main() and pretend nothing happened.

Line 3 is definitely undefined behaviour, since you're trying to deleting memory at an address that is not on the heap.

Related

Deleted variable can still be accessed in c++? [duplicate]

This question already has answers here:
C++ delete - It deletes my objects but I can still access the data?
(13 answers)
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
I created a simple project just to test how deleting variable works but i encountered a strange thing...
I created three int variables (1 stack based and 2 heap based) and when i deleted the heap variables using delete i still could access them. I can print them or change their value but how? Isn't delete supposed to permanently delete the variable from memory and also another question.... Why stack based variables can't be deleted using free() or delete?
Here is the (C++) script -
#include<iostream>
using namespace std;
void Stuff()
{
int* heap_int = (int*)malloc(4); //Heap based variable
*heap_int = 500;
int stack_int = 5; //Stack based variable
int* calloc_int = (int*)calloc(1,2); //Heap based variable
*calloc_int = 600;
std::cout << "Value (HeapInt) : " << *heap_int << "\n"; //Prints 500
std::cout << "Value (CallocInt) : " << *calloc_int << "\n"; //Prints 600
std::cout << "Value (StackInt) : " << stack_int << "\n"; //Prints 5
delete heap_int;
delete calloc_int;
//delete stack_int; (will not work)
std::cout << "\nValue after delete (HeapInt) : " << *heap_int << "\n"; //Still prints 500
std::cout << "Value after delete (CallocInt) : " << *calloc_int << "\n"; //Still Prints 600
std::cout << "Value after delete (StackInt) : " << stack_int << std::endl; //Prints 5
*heap_int = 82;
}
int main()
{
Stuff();
}
I heard in online tutorials that heap based variables only get freed if we used delete or free() (unlike stack variables who get freed automatically when their scope ends) then why can't i access an heap based variable out of scope like this...?
#include<iostream>
void Function()
{
int* variable = new int;
*variable = 6;
}
int main()
{
*variable = 9; //Error says "Use of Undeclared identifier variable"
}
Reading the contents of a free'd or deleted memory address is called undefined behavior.
delete heap_int;
std::cout << "\nValue after delete (HeapInt) : " << *heap_int << "\n"; //Still prints 500
You might still be able to see the previous value at a deleted address, but it's definitely not guaranteed. As soon as the next malloc/new happens (or technically at any time), the memory manager might re-use that address for another object and overwrite what's there.
And this:
*heap_int = 82;
Similarly, writing to a deleted address is even worse undefined behavior - chances are high you have corrupted your program's behavior in strange ways, or at best, a fast crash.
why can't i access an heap based variable out of scope like this...?
Because you can't access any variable that's not in your scope or the parent scope. In your case, code in main can only access variables in that function or variables declared at global scope. That's the whole point of scope!

Postfix in C++ not behaving like I'd expect [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 3 years ago.
I understand the basic differences between prefix/postfix notation for decrement/increment operators in C++. However, there is something going on in the next example that stumps me.
The code I shared below prints the following.
5*4**3***4****2*****1
But I would have guessed it would print this.
5*4**4***3****2*****1
How is this happening? Is something going on with pushing/popping to/from the stack?
int var = 5;
cout << var-- << '*'; //prints 5 and then decrements to 4.
cout << var << "**"; //The value of var (now 4)
//is printed to the console.
//The next line prints 3***4****.
//I would have guessed it prints 4***3****.
cout << var-- << "***" << var-- << "****";
//No matter what the above line prints,
//the value of var after the above lines is 2, so...
cout << var-- << "*****" << var << endl; //...Print 2, decrement to 1
//and then 1 is finally printed.
Welcome to the strange world of undefined behaviour. Calling an increment or decrement operator twice on the same variable, in the same statement, is undefined behaviour, so don't do it :)
#include <iostream>
int main()
{
int i = 1;
// should this print 9, 10, or 12? Compilers will vary...
std::cout << (++i + ++i + ++i) << std::endl;
return 0;
}
The problem in this line:
cout << var-- << "***" << var-- << "****";
is undefined behaviour because you using post-decrement twice in a single statement.

what is the difference betwee new int() and new int[] [duplicate]

This question already has answers here:
Difference between operator new() and operator new[]()?
(5 answers)
Closed 5 years ago.
int main()
{
int *y = new int(5);
cout << "y = " << y << " &y = " << &y << " *y = " << *y << endl;
int *p = new int[5];
cout << "p = " << p << " &p = " << &p << " *p =" << *p << endl;
}
one used [] and another one used (), what's the different and how it works? Can someone help to explain to me? Thanks!
int *y = new int(5)
This allocates a single int and sets its value to 5, then assigns y to point at the allocated int.
int *p = new int[5]
This allocates an array of 5 ints, whose values are initially undefined, then assigns p to point at the first int in the allocated array.
You output so many things in your std::cout but most of them don't matter.
try
std::cout << sizeof(int(5)) << " " << sizeof(int[5]) << "\n";
which will output
4 20
since int(5) means a single integer initialised with 5. So sizeof yields the size of an int.
On the other hand, int[5] is what you expect: an array of 5 integers, so sizeof yields 5*sizeof(int).
Two more remarks:
creating good old arrays with new definitely is something a beginner should refrain from. If you need dynamically sized indexable storage, use std::vector. There is no speed panalty.
refrain from using namespace std; simply type the std::, that makes the code more readable and clearly separates your stuff from library stuff.

changing the location a pointer-to-pointer points to while maintaining the value of two other pointers

So, I have been trying to learn C++ and in the tutorial book that I am reading, I have gotten stuck on a problem of pointers-to-pointers. What I am trying to do change the pointer a pointer-to-pointer is pointing to without changing the value of the original pointer. Here's some code...
#include <iostream>
void testFunc(int **func_p_to_p) {
int *createdPointer = new int(10);
*func_p_to_p = createdPointer;
cout << **func_p_to_p << endl; //prints 10 as I expect
}
int main() {
int **main_p_to_p = NULL;
int *mainPointer = new int(5);
main_p_to_p = &mainPointer;
testFunc(main_p_to_p);
cout << **test << endl;//prints 10, I expect this...
cout << *mainPointer << endl; //prints 10 as well, I don't want that.
}
I asked a similar question about this earlier, here and I understand sort of what is going on. However, I can't seem to figure out how I would change where a pointer-to-pointer is pointing to without changing the original value. Could anyone explain how I would do this? Thanks.
In the line
*func_p_to_p = createdPointer;
you first follow your pointer-pointer to what it is pointing to: The address of int *mainPointer.
Next you assign a new value to this pointer, the value of createdPointer which is the address of new int(10).
So your mainPointer is now changed to target the same memory as createdPointer. Does this make any sense to you?
You can't do that. main_p_to_p points to mainPointer, so modifying *main_p_to_p modifies mainPointer, full stop.
You might be looking for this, though:
int main() {
int **main_p_to_p = NULL;
int *mainPointer = new int(5);
int *secondPointer = mainPointer;
main_p_to_p = &secondPointer;
// prints 5 5 5
cout << *mainPointer << " " << *secondPointer << " " << **main_p_to_p << std::endl;
testFunc(main_p_to_p);
// prints 5 10 10
cout << *mainPointer << " " << *secondPointer << " " << **main_p_to_p << std::endl;
}
Note that you don't need the main_p_to_p variable, but I left it in for consistency with the question.

c++ strange std::cout behaviour using pointers [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the correct answer for cout << c++ << c;?
I just ouputted text, when I suddenly noticed.
#include <iostream>
int main()
{
int array[] = {1,2,3,4};
int *p = array;
std::cout << *p << "___" << *(p++) << "\n";
// output is 1__1. Strange, but I used brackets! it should be at
// first incremented, not clear.
p = array;
std::cout << *p << "___" << *(++p) << "\n";
// output is 2_2 fine, why first number was affected? I didn't intend
// to increment it, but it was incremented
p=array;
std::cout << *p << "___" << *(p + 1) << "\n";
// output is 1_2 - as it was expected
p = array;
return 0;
}
Such behaviour is strange for me, why is it so?
You are causing undefined behaviour, so anything can happen and there's no point in speculating about why.
The expression
std::cout<<*p<<"___"<<*(p++)<<"\n"
Is one example: the order of evaluation of all the things between << is unspecified, so *p and *(p++) are unsequenced with respect to each other (i.e. the compiler is not required do do either one first). You are not allowed to modify a variable and then use it without the modification and usage being sequenced, and so this causes undefined behaviour.
The same thing applies to all the other places in that program where a variable is modified and used unsequenced separately in the same expression.