Object constructed at a predetermined position in memory - SEGFAULT - c++

I have this piece of code
int main()
{
int *b = new int(8);
cout<<" &b = "<<b<<endl;
delete b;
void *place = (void*)0x3c0fa8; //in my output i am getting this value in &b
int *i = new(place) int(8);
system("PAUSE");
return 0;
}
My doubt is that i have allocate space for "b", and deleted it, now if i allocate another integer space, it comes out to be the same location as allocated previously, now if i forcefully put integer value to this value(after delete), i am getting SEGFAULT.
What's wrong in this code?
Thanks.

It is not guaranteed that each time b will be allocated at same memory location, in fact it is extremely uncommon and you should not rely on this.
And for this case, place actually points to an invalid address, and accessing it causes Segfault.
Even if place points to same location where b were allocated, after deleting b, the memory is de-allocated and does not belong to your program. Before int *i = new(place) int(8); gets executed, that memory location may have been allocated by any other process. Hence again accessing it will cause Segfault.

Using memory that was allocated from the heap, after it has been freed (with delete) is undefined behaviour. For all we know, that cell of the heap may have been completely freed back to the OS [and thus no longer available as memory in your process] (in fact, Windows pretty much calls into the OS directly for all heap allocations, and it is possible that it frees the entire lump of memory that the heap is in).
However, it's more likely that the second new call works out, and you are simply overwriting some piece of heap memory that belongs to the heap, so when the code tries to exit (and free some stuff allocated before main), it falls over.
If you were to do it
int main()
{
int *b = new int(8);
cout<<" &b = "<<b<<endl;
// delete b;
int *i = new(b) int(8);
}
it has a good chance of working, since you are no longer using heap memory AFTER it has been freed. (Of course, you may want to change the second 8 to a 9 or something to see the difference... ;)

It looks like you are using the placement new wrong. The placement new operator is used for constructing stuff in a pre-defined location. It's meant to be used like this (This question might be useful too):
char *buffer = new char[sizeof(string)];
string *str = new (buffer) string("hello, world");//<-- this is your placement new
As you can see, the memory in which you are constructing, should be acquired by you in advance. In your example, however, you are not doing it, and trying to write into memory that you have not acquired before, which leads to segfault.
Also, as the other answer mentioned, you are by no means guaranteed to be getting the same address for b each time. Moreover, even if you get lucky, and place points to the same address as b, you still are trying to write into the memory that doesn't belong to you, since you do a delete b beforehand.

Related

Deleting Pointers

I wanted to ask, is dynamically creating a pointer, and then changing a pointer address to something else still deleting the original allocated space?
for example:
int main()
{
int c = 50;
// Memory leak
int * q = new int;
q = & c;
delete q;
}
What exactly is getting deleted or happening?
Thanks!
What exactly is getting deleted or happening?
Memory leaking and undefined behaviour.
When you do q = & c; you are losing your only tracking of the memory allocated by new int. Noone keeps track of this for you, there is no garbage collector, it is simply lost and cannot be recovered.
When you then do delete q; (where q is assigned to &c) you are deleting memory that you didn't allocate, and worse you are deleting memory on the stack. Either of these will result in undefined behavior.
This is an excellent preface into why you should avoid using pointers in circumstances where you don't need them. In this case, there is no reason dynamically allocate your int. If you really need a pointer, use a c++11 smart pointer (or boost if you don't have c++11). There are increasingly rare cases where you really do need a raw c type pointer. You should read Effective Modern c++ Chapter 4 for excellent detail on this subject.
is dynamically creating a pointer, and then changing a pointer address to something else still deleting the original allocated space?
No. delete will deallocate the memory to which its operand points. You must delete the same block of memory that you obtained from new.
int c = 50;
int * q = new int;
int * r = q;
q = & c;
delete q; // WRONG! q points to something you didn't get from new
delete r; // OK! p points to the block you got from new
To be even more clear, delete doesn't care about what variable it operates on, it only cares about what that variable points to. In the last line above, r points to the block that was originally pointed to by q and allocated by new, so you can safely delete it. q points to statically allocated memory, not something you got from new, so you can't delete it.
Instead of changing where q points, though, you can copy the value you want into the space that q points to:
int c = 50;
int * q = new int;
*q = c;
delete q; // OK! q still points to the same place
Here you're changing the value stored in the location to which q points, but you're not changing q itself. q still points to the block you got from new, so it's safe to delete it.
You code will (try to) delete c. There's no memory management or anything like that in C/C++. delete will try to delete whatever the given pointer points to, and and whatever is not deleted (either by calling delete for variables created with a call to new, or by leaving the scope for local variables) will remain in memory until the program ends.
Notice that trying to delete a local variable will propably cause a crash, since delete actually checks (in a very basic manner) what it deletes - at least to know how much memory has actually been allocated at that address. And at this check, it will propably notice that c doesn't include this information, or that it isn't even at the right end of the memory space, so it will crash.
It will crash because c is created in the stack memory section. If you're lucky and the program didn't crash you aren still leaking memory because the q reference is lost.
First answer is to your question:-
I wanted to ask, is dynamically creating a pointer
We don't create a pointer dynamically. Pointers are just a variable like other variable in C and C++. Difference is, pointer is a variable which can store the address of a particular memory location. In run time you just dynamically allocate memory and assign the address of first address location of that memory size into it.
Now what will happen if you don't delete/free the memory and assign a new address to it. In that case memory will not be release/freed and that can not be use anymore as that will never be marked as free by OS. When you free/delete memory O/S mark that area as free to use, and your running process can utilize it in future. That is call proper memory management. Improper memory manage leads your program to memory leak.

Using new for an already valid pointer

If I've already used new to allocate memory to int* p, but then if I want use new again, will the previously allocated memory remain valid?
int *p;
p= new int[5]; //is this going to remain valid after the following statement?
p= new int[10];
If yes, then am I required to delete[] it? I tried doing that but the compiler says that the pointer is valid, so I can't delete it. Is there any other way to get rid of the previously allocated memory?
The second use of new[] is, in itself, completely independent of the first. The second use of new[] does not in any way invalidate the first block of memory that you allocated.
When you allocate memory, you are asking the system to allocate memory, and tell you the address of the memory that it, the system, allocated. It is your responsibility to remember that address so that you can refer to it in the future. You need to be able to refer to the memory in order to access it and eventually deallocate it.
This is your code:
int *p;
p= new int[5];
p= new int[10];
The first assignment records the address of the first allocated block. The second assignment overwrites that value with the address of the second block.
So, the problem you have is that you no longer have a variable that contains the address of the first block of memory. Whilst that first block is still valid, you are unable to refer to it. In particular, since you can no longer refer to it, you cannot deallocate it and so it will be leaked.
If you wish to be able to deallocate both blocks of memory, then you have to be able to refer to both blocks. Which means that you must have two variables to hold the two distinct addresses.
int* p1 = new int[5];
int* p2 = new int[10];
Now you can refer to blocks blocks separately. When you are done, deallocate the memory:
delete[] p1;
delete[] p2;
On the other hand, if you want to delete the memory before allocating a new block, you can do that:
int* p = new int[5];
// use p
detete[] p;
int* p = new int[10];
// use p
delete[] p;
The prev remain somewhere on the heap. You can use valgrind to verify that. If you want to use the sane pointer again and again you might consider to create a function that delete the last allocation and allicate new space each time...
To add to what David Heffernan said, when you have this statement:
int *p;
p= new int[5];
don't think of p as being assigned to the memory that was allocated. The memory exists independently of p, but you're using p as a sort of post-it note to jot down where that memory is located. When you assign a new value to p, you're simply overwriting your note. You haven't done anything to the memory that was allocated-- you just don't know where it is anymore.
If the memory you previously allocated is not needed anymore, you have to use delete [] to free the memory. Otherwise, the memory is still out there, but you have no way to access it any more, thus a memory leak.
You will need to delete[] p; in order to avoid memory leak. The memory doesn't get released by itself. What's the exact information the compiler is giving in terms of "can't delete it"?

"Delete" not de-allocating dynamic memory [duplicate]

This question already has answers here:
C++ delete - It deletes my objects but I can still access the data?
(13 answers)
Closed 9 years ago.
I'm facing an issue. I wrote the following programme:
void main()
{
int *ptr;
ptr=new int;
cout<<ptr<<endl;
cout<<&ptr<<endl;
delete ptr;
// ptr= NULL;
cout<<ptr<<endl;
cout<<&ptr<<endl;
}
The output of the programme is:
0x00431810
0x0018FF44
0x00431810
0x0018FF44
"&ptr" would definitely be the same because it is ptr's own address. But 1st and third line of output clearly shows that "ptr" is pointing to the same memory location even after the "delete" is called. Why? If this is the case why do we have "delete" and not just rely on NULLING the pointer. I know that more than one pointers can point to a memory location but yeah "delete" is useless. No ? That's so confusing. please help. I've an exam tomorrow.
delete ptr does not change the value of the pointer, but it does free the memory.
Note that dereferencing ptr after freeing the memory would trigger undefined behaviour.
When you call new, you are asking the computer to allocate some memory on the heap and returns a pointer to where that is on the heap.
Calling delete does the opposite in that it tells the computer to free the memory the pointer is pointing to from the heap. This means that it can be reused by your program at a later stage.
However, it does not change the value of the pointer. It is good practise to set the pointers value to NULL. This is because, where the pointer is now pointing to could contain anything (the computer is free to reuse this memory for something else). Were you to use this pointer, it is undefined what will happen.
If you just change the pointer to NULL, then all that does it forget where you allocated the memory. Because C++ is not a managed language, it won't detect you don't have any pointer to that memory, so the memory will become lost as you can't access it (you don't know where it is) but the computer can't reuse it (it doesn't know you are done with it).
If you use a managed language like C# or Java, when there are no pointers to something on the heap, the computer frees it (known as Garbage Collection) but this comes with performance overheads so C++ leaves it up to the programmer.
pointer doesn't know if the memory is valid or corrupted. You can make pointer to point at any address that you can address (that will fit into pointer). For example on my machine pointer has 8 bytes size so I can do
int main(int argc, char** argv) {
int *ptr;
ptr=new int;
cout<<ptr<<endl;
cout<<&ptr<<endl;
delete ptr;
//ptr= NULL;
cout<<ptr<<endl;
cout<<&ptr<<endl;
ptr = (int*) 0xffffffff;
cout<<ptr<<endl; //prints 0xffffffff
ptr = (int*) 0xffffffffffffffff;
cout<<ptr<<endl; //prints 0xffffffffffffffff
ptr = (int*) 0xffffffffffffffff1;
cout<<ptr<<endl; //prints 0xfffffffffffffff1 truncated
ptr = (int*) 0xffffffffffffffff321;
cout<<ptr<<endl; //prints 0xfffffffffffff321 truncated
return 0;
}
When you are using new it will allocate memory at some address on the heap and return you a pointer to this address.
void* operator new (std::size_t size) throw (std::bad_alloc);
Pointer and memory are two distinguished things. In particular you can even specify an address which you want to use for allocation by hand(using placement new syntax):
int* ptr = new (0xff1256) int;
//correct if the memory at 0xff1256 is preallocated
//because placement new only creates object at address
//doesn't allocate memory
"ptr" is pointing to the same memory location even after the "delete"
is called. Why?
In the same way delete ptr only deallocates memory, leaving the pointer intact (this is a good practice though to assign NULL to a pointer immediately after call to delete). It only deallocate the memory, it is not interested in your pointer but in the address where to free memory. Allocating memory or deallocating it is done by operating system (i.e.the memory is being marked as allocated).
From the documentation,
Deallocates the memory block pointed by ptr (if not null), releasing
the storage space previously allocated to it by a call to operator new
and rendering that pointer location invalid.
That means, delete marks the location to be reused by any other process for any other purpose. It never says that, it will initialize the memory block to any random value, so that the earlier stored data can never be accessed again. So, there is always the possibility of having your data even after the call to delete. But, again, it is just one of the possibility of Undefined Behavior. Thats' why coders, make the pointer NULL after deallocating it.

Simple memory issue exercise

I'm working mostly in high-level programming languages, but so yesterday a friend asked me to help him solve a simple C++ exercise and while I was working on it I wrote this piece of code:
for (int x = 0; x < 10; x++){
int a, b, c;
a = x;
b = x*2;
c = x+5;
}
My question here is: will this cause a memory leak making a, b, c always be created in different locations of memory, or will they always be overwritten with every loop?
Memory leak can happen only if you have dynamically allocated variables(by calling new or new [] or malloc or calloc). There are none in your code so NO.
What you have are local or automatic variables. As the name says automatic variables are implicitly deallocated when the scope {} in which they are created ends.
a, b and c will be allocated on the stack. Automatic variables can never cause a memory leak unless the types themselves cause a leak through their constructor and/or destructor.
Regarding the question of whether they will overwrite each loop: I strongly suspect that every single compiler on Earth will do it that way but, in principle, this is not guaranteed. If you look at the assembly output you will discover that either (a) all the variables are in registers or (b) they retrieved as fixed offsets from the stack pointer. Since the same assembly is being executed each time through the loop they will, indeed, be overwriting.
You ask three questions:
this will cause a memory leak
No, there is no memory leak here. A memory leak, as that term is commonly used, requires a new without a delete, a new[] without a delete[], or a malloc() without a free().
a, b, c always be created in different locations of memory
They might be. They might not be. This is an implementation detail of which you program need not be aware. All you need to know is that the objects are created at the line that defines them, and destroyed at the closing brace of that scope.
they will be always overwritten with every loop?
They might be. They might not be. This is an implementation detail of which your program need not be aware. Regardless of whether they are overwritten, they are destroyed each time around the loop.
The same place in memory will be used to store the values in a, b and c in every iteration of the loop.
if you create a variable like this
int i = 5;
The compiler will put them on the stack, you don't have to deallocate the int.
however if you create a int on the heap,
int* i = new int; /*C++ style*/
int* j= (int*) malloc(sizeof(int)); /*C style*/
You do have deallocate the memory like this:
delete i; /*C++ style*/
free(j); /*C style*/
otherwise you'll have a memory leak.
most importantly you don't want to mix the c- and c++-style of memory handling.

Where my memory is alloced, Stack or Heap, Can I find it at Run-time?

I know that memory alloced using new, gets its space in heap, and so we need to delete it before program ends, to avoid memory leak.
Let's look at this program...
Case 1:
char *MyData = new char[20];
_tcscpy(MyData,"Value");
.
.
.
delete[] MyData; MyData = NULL;
Case 2:
char *MyData = new char[20];
MyData = "Value";
.
.
.
delete[] MyData; MyData = NULL;
In case 2, instead of allocating value to the heap memory, it is pointing to a string literal.
Now when we do a delete it would crash, AS EXPECTED, since it is not trying to delete a heap memory.
Is there a way to know where the pointer is pointing to heap or stack?
By this the programmer
Will not try to delete any stack memory
He can investigate why does this ponter, that was pointing to a heap memory initially, is made to refer local literals? What happened to the heap memory in the middle? Is it being made to point by another pointer and delete elsewhere and all that?
Is there a way to know where the pointer is pointing to heap or stack?
You can know this only if you remember it at the point of allocation. What you do in this case is to store your pointers in smart pointer classes and store this in the class code.
If you use boost::shared_ptr as an example you can do this:
template<typename T> void no_delete(T* ptr) { /* do nothing here */ }
class YourDataType; // defined elsewhere
boost::shared_ptr<YourDataType> heap_ptr(new YourDataType()); // delete at scope end
YourDataType stackData;
boost::shared_ptr<YourDataType> stack_ptr(&stackData, &no_delete); // never deleted
As soon as you need that knowledge you have already lost. Why? Because then even if you omit the wrong delete[], you still have a memory leak.
The one who creates the memory should always be the one who deletes it. If at some occasion a pointer might get lost (or overwritten) then you have to keep a copy of it for the proper delete.
There is no way in Standard C++ of determining whether a pointer points to dynamically allocated memory or not. And note that string literals are not allocated on the stack.
As most of the users said here there's no standard way to discover which memory you're dealing with.
Also, as many users pointed out, it;s a kinda perverted situation where you pass a pointer to a function which should delete it automatically if it's allocated on heap.
But if you insist, nevertheless there are some ways to discover which memory belongs to which type.
You actually deal with 3 types of memory
Stack
Heap
Global
For instance:
char* p = new char[10]; // p is a pointer, points to heap-allocated memory
char* p = "Hello, world!"; // p is a pointer, points to the global memory
char p[] = "Hello, world!"; // p is a buffer allocated on the stack and initialized with the string
Now let's distinguish them. I'll describe this in terms of Windows API and x86 assembler (since this is what I know :))
Let's start from stack memory.
bool IsStackPtr(PVOID pPtr)
{
// Get the stack pointer
PBYTE pEsp;
_asm {
mov pEsp, esp
};
// Query the accessible stack region
MEMORY_BASIC_INFORMATION mbi;
VERIFY(VirtualQuery(pEsp, &mbi, sizeof(mbi)));
// the accessible stack memory starts at mbi.BaseAddress and lasts for mbi.RegionSize
return (pPtr >= mbi.BaseAddress) && (pPtr < PBYTE(mbi.BaseAddress) + mbi.RegionSize);
}
If the pointer is allocated on the stack of another thread you should get its stack pointer by GetThreadContext instead of just taking the EIP register value.
Global memory
bool IsGlobalPtr(PVOID pPtr)
{
MEMORY_BASIC_INFORMATION mbi;
VERIFY(VirtualQuery(pPtr, &mbi, sizeof(mbi)));
// Global memory allocated (mapped) at once for the whole executable
return mbi.AllocationBase == GetModuleHandle(NULL);
}
If you're writing a DLL you should put its module handle (which is actually its base mapping pointer) instead of GetModuleHandle(NULL).
Heap
Theoretically you may assume that if the memory is neither global nor stack - it's allocated on heap.
But there's is actually a big ambiguity here.
You should know that there're different implementations of the heap (such as raw Windows heap accessed by HeapAlloc/HeapFree, or CRT-wrapped malloc/free or new/delete).
You may delete such a block via delete operator only if you know for sure it was either stack/global pointer or it was allocated via new.
In conclusion:
It's a kinda pervert trick. Should not be used generally. Better to provide some extra information with the pointer which tells how to release it.
You can only use it if you know for sure on which heap the memory was allocated (in case it's a heap memory).
I think there is no (easy) way how to tell where the memory is allocated (you might be able to determine it using a debugger, perhaps, but that is obviously not what you want). The bottom line is: never do the thing you did in case 2.
In case 2, MyData = "Value" causes a memory leak since there is no longer a reference to the memory returned from new.
There is no easy way or standard way for doing this. You can intercept the heap allocation function(s) and put each memory allocated zone in a list. Your "IsHeap" function should check if the zone passed to the function is the one from the list. This is just a hint - it is almost impossible to do this in a cross-platform manner.
But then again - why would you need that?