从动态创建的缓冲区中删除子缓冲区

时间:2014-06-12 17:30:01

标签: c++

char* ptr = new char[512]; // also malloc() can be used
ptr = ptr + 10;
delete[] ptr; // free() if memory allocated by malloc

正如我们所知,分配内存new和malloc在某处保存分配的内存大小(在哪里?取决于编译器实现)。在释放内存时,delete和free()使用此保存的大小值。 在我的情况下,我将起始指针移动了10个字节。我的问题是: 是内存泄漏的情况吗? 未定义的行为? 或者它会尝试在512之后释放下一个额外的10个字节?

4 个答案:

答案 0 :(得分:11)

这是未定义的行为,您必须释放或删除相同的指针。

来自 ISO / IEC 9899:201x

  

7.22.3.3自由功能

     
    

free函数导致ptr指向的空间被释放,即make     可供进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果     该参数与先前由内存管理返回的指针不匹配     函数,或者如果通过调用free或realloc释放空间,则     行为未定义。

  

关于未定义的行为:

  

3.4.3(1)未定义的行为:

     
    

行为,在使用不可移植或错误的程序构造或错误数据时,     本国际标准没有要求

  

答案 1 :(得分:4)

这是未定义的行为。

来自http://en.cppreference.com/w/cpp/language/delete

  

对于第一个(非数组)形式,表达式必须是指针或类型上下文可隐式转换为指针,并且其值必须为null或指向由new-expression创建的非数组对象的指针,或指向由new-expression创建的非数组对象的基础子对象的指针(如果是其他任何内容,则行为未定义)。

答案 2 :(得分:2)

如果您指出delete[]来自new[]的内容,那么该行为是未定义的行为。这同样适用于free()malloc()或类似的分配函数对。

可能会导致内存损坏和/或崩溃。

答案 3 :(得分:0)

以上所有都是正确的。我添加以下内容:

C ++没有指定内存分配器的工作方式。一种常见的方法是使用固定大小的块(通常为2的幂)。这是一种简化内存分配和释放的机制。

在这样的系统中,您编码从512字节池中获取块。

然后你试图把它改成一个502字节和10字节的块,这些都不是内存管理系统可以处理的。

某些内存管理系统在返回地址之前和块结束之后对数据进行编码。如果它允许你想要做的事情,这样的系统就会搞砸了。