C++ 编译器是否将这种形式的"new"视为堆栈内存?

Does c++ compiler treat "new" in this form as stack memory?

本文关键字:new 堆栈 内存 是否 编译器 C++      更新时间:2023-10-16

可能的重复:
为什么使用"new"会导致内存泄漏?

我遇到了这样的小问题

int main() {
int i = *new int;
delete &i;
return 0;
}

它可以编译,但是在执行时,shell给出以下内容:

a.out(38303) malloc:对象 0x7fff5fbff8cc 的 *** 错误:未分配正在释放的指针 在malloc_error_break中设置断点以进行调试 中止陷阱

int main() {
int *i = new int;
delete i;
return 0;
}

按预期正常运行。

困扰我的是,第一种情况不是使用"new"运算符来分配内存吗? 为什么删除时会导致错误?

我已经在网上搜索了好几次,但我找不到合适的解释。 谁能告诉我为什么错了?谢谢:)

问题是您有内存泄漏,并且您正在删除未动态分配的内容。为什么?因为您动态分配int所以将其值复制到i中。然后,您尝试通过指向对象的指针删除对象i,但i不是动态分配的 - 它的值只是从某个东西初始化的。您丢失了指向实际动态分配的对象的任何指针。

从图中讲,首先new int,创建一个具有动态存储持续时间的int对象,并返回指向该 int 的指针:

_____        ______
Heap:  | int | <--- | int* |
|_____|      |______|

然后取消引用指针,为您提供int对象并将其值复制到具有自动存储持续时间的int对象。在此之后,您从new获得的指针将丢失,因为您没有将其存储在任何地方。

_____
Heap:  | int |
|_____|
_____
Stack: | int |
|_____|

然后,您获取具有自动存储持续时间的int的地址并尝试delete它。

_____
Heap:  | int |
|_____|
_____        ______
Stack: | int | <--- | int* | <-- Cannot delete because it was
|_____|      |______|     not dynamically allocated

你可能想写的是这样的:

int main() {
int& i = *new int;   // note the reference type
delete &i;
return 0;
}

但请注意,如果他看到该代码,没有一个头脑正常的人会雇用你。

第一种情况不是使用"new"运算符来分配内存吗?

确实如此。但是你没有抓住指向它的指针。相反,您将它的(未初始化的)值复制到局部变量中,并泄漏分配的内存;您丢失了指向内存的唯一指针,因此无法删除它。

为什么删除时会导致错误?

因为&i指向局部变量i,而不是分配的内存。删除任何未分配new的内容都是错误的,包括局部变量。

delete &i失败,因为您尝试deletenew未返回的指针。这是未定义的行为。

int i = *new int;

您正在将新分配的int的值分配给i。指针丢失。

int main() {
int i = *new int;
delete &i;
return 0;
}

您的第一行仅设置i的值。它仍然存在于堆栈上,因此将其地址传递给delete是非法的。