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

Delete sub buffer from a dynamically created buffer

本文关键字:缓冲区 删除 动态 创建      更新时间:2023-10-16
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字节?

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

源自ISO/IEC 9899:201x:

7.22.3.3自由函数

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

关于未定义行为:

3.4.3(1)未定义行为:

行为,在使用不可移植的或错误的程序结构或错误的数据时,

未定义行为。

从http://en.cppreference.com/w/cpp/language/delete

对于第一种(非数组)形式,expression必须是指针或在上下文中隐式转换为指针的类类型,其值必须为null或指向new-expression创建的非数组对象的指针,或指向new-expression创建的非数组对象的基子对象的指针(如果是其他类型,则行为未定义)。

如果你给delete[]的指针,你没有从new[]得到,这是未定义的行为。对于free()malloc()或类似的分配函数对也是如此。

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

以上均正确。我添加了以下内容:

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

在这样的系统中,代码从512字节池中获取一个块。

然后你试图把它变成502字节和10字节的块,这两个内存管理系统都不能处理。

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