0

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.

instance
  • 1,366
  • 15
  • 23

3 Answers3

3

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.

Rakib
  • 7,435
  • 7
  • 29
  • 45
1

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... ;)

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

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.

Community
  • 1
  • 1
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
  • @SinegrOfTheFall in first line you are just allocating a memory for a pointer, i suppose it can be anything (char, int etc) not specifically string like - char *buffer = new char[sizeof(int)]; since all pointers have same size. – instance May 23 '14 at 08:14
  • @instance, yes, you are right, but what's the point? The thing is that you _need_ to allocate memory first, and _then_ use the placement `new` on that allocated memory. In your example in the question, however, you are freeing the memory with `delete`, and _then_ trying to write into it. Since that memory is not yours, you are getting your segfault. – SingerOfTheFall May 23 '14 at 08:23