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个字节?
答案 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字节的块,这些都不是内存管理系统可以处理的。
某些内存管理系统在返回地址之前和块结束之后对数据进行编码。如果它允许你想要做的事情,这样的系统就会搞砸了。