Is there any danger in calling free() or delete in

2019-01-12 06:33发布

Possible Duplicate:
( POD )freeing memory : is delete[] equal to delete ?

Does delete deallocate the elements beyond the first in an array?

char *s = new char[n];
delete s;

Does it matter in the above case seeing as all the elements of s are allocated contiguously, and it shouldn't be possible to delete only a portion of the array?

For more complex types, would delete call the destructor of objects beyond the first one?

Object *p = new Object[n];
delete p;

How can delete[] deduce the number of Objects beyond the first, wouldn't this mean it must know the size of the allocated memory region? What if the memory region was allocated with some overhang for performance reasons? For example one could assume that not all allocators would provide a granularity of a single byte. Then any particular allocation could exceed the required size for each element by a whole element or more.

For primitive types, such as char, int, is there any difference between:

int *p = new int[n];
delete p;
delete[] p;
free p;

Except for the routes taken by the respective calls through the delete->free deallocation machinery?

10条回答
Viruses.
2楼-- · 2019-01-12 07:19

For primitive types, such as char, int, is there any difference between:

I'd say you'll get undefined behaviour. So you shouldn't count on stable behaviour. You should always use new/delete, new[]/delete[] and malloc/free pairs.

查看更多
Rolldiameter
3楼-- · 2019-01-12 07:21

Does delete deallocate the elements beyond the first in an array?

No. delete will deallocate only the first element regardless on which compiler you do this. It may work in some cases but that's co-incidental.

Does it matter in the above case seeing as all the elements of s are allocated contiguously, and it shouldn't be possible to delete only a portion of the array?

Depends on how the memory is marke as free. Again implementation dependant.

For more complex types, would delete call the destructor of objects beyond the first one?

No. Try this:

#include <cstdio>

class DelTest {
    static int next;
    int i;
public:
    DelTest() : i(next++) { printf("Allocated %d\n", i); }
    ~DelTest(){ printf("Deleted %d\n", i); }
};

int DelTest::next = 0;

int main(){
    DelTest *p = new DelTest[5];
    delete p;
    return 0;
}

How can delete[] deduce the number of Objects beyond the first, wouldn't this mean it must know the size of the allocated memory region?

Yes, the size is stored some place. Where it is stored depends on implementation. Example, the allocator could store the size in a header preceding the allocated address.

What if the memory region was allocated with some overhang for performance reasons? For example one could assume that not all allocators would provide a granularity of a single byte. Then any particular allocation could exceed the required size for each element by a whole element or more.

It is for this reason that the returned address is made to align to word boundaries. The "overhang" can be seen using the sizeof operator and applies to objects on the stack as well.

For primitive types, such as char, int, is there any difference between ...?

Yes. malloc and new could be using separate blocks of memory. Even if this were not the case, it's a good practice not to assume they are the same.

查看更多
我命由我不由天
4楼-- · 2019-01-12 07:22

Read the FAQ: 16.3 Can I free() pointers allocated with new? Can I delete pointers allocated with malloc()?

Does it matter in the above case seeing as all the elements of s are allocated contiguously, and it shouldn't be possible to delete only a portion of the array?

Yes it does.

How can delete[] deduce the number of Objects beyond the first, wouldn't this mean it must know the size of the allocated memory region?

The compiler needs to know. See FAQ 16.11

Because the compiler stores that information.

What I mean is the compiler needs different deletes to generate appropriate book-keeping code. I hope this is clear now.

查看更多
forever°为你锁心
5楼-- · 2019-01-12 07:23

It's undefined behaviour (most likely will corrupt heap or crash the program immediately) and you should never do it. Only free memory with a primitive corresponding to the one used to allocate that memory.

Violating this rule may lead to proper functioning by coincidence, but the program can break once anything is changed - the compiler, the runtime, the compiler settings. You should never rely on such proper functioning and expect it.

delete[] uses compiler-specific service data for determining the number of elements. Usually a bigger block is allocated when new[] is called, the number is stored at the beginning and the caller is given the address behind the stored number. Anyway delete[] relies on the block being allocated by new[], not anything else. If you pair anything except new[] with delete[] or vice versa you run into undefined behaviour.

查看更多
登录 后发表回答