为变量分配新值时泄漏内存?

发布于 2024-11-28 20:49:40 字数 461 浏览 5 评论 0原文

是的,我是从 Java 开始学习 C++ 的人之一,被自动垃圾收集器宠坏了。在一种特殊情况下,我想知道我是否泄漏了内存。让我们在 C++ 中考虑一下:

bool *test = new bool(false);
test = new bool(true);
delete test;

我这里是否泄漏了内存?或者我应该在分配新值之前先调用delete?像这样:

bool *test = new bool(false);
delete test;
test = new bool(true);
delete test;

我的直觉告诉我第一个是正确的,因为指针 test 指向内存中的同一地址,并且为它的变量分配一个新值,不会改变这个地址。或者 new 运算符是否在内存中分配不同的地址?谁能给我一个线索,还是我完全弄错了?

Yes, I'm one of those fellows that is learning C++ coming from Java, being spoiled with an automatic garbage collector. There's a particular situation where I'm wondering whether I'm leaking memory or not. Let's consider in C++:

bool *test = new bool(false);
test = new bool(true);
delete test;

Am I leaking memory here? Or should I first call delete before assigning a new value? Like this:

bool *test = new bool(false);
delete test;
test = new bool(true);
delete test;

My gut feeling tells me the first is right, as the pointer test points at the same address in memory, and assigning a new value to its variable, will not change this address. Or does the new operator allocate a different address in memory? Can anyone give me a clue, or did I get it wrong all together?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

寄人书 2024-12-05 20:49:40

是的,你正在泄漏,而 C++ 的方法是:

bool test = false;
test = true; 

// ta-da - no leak.

你可以采用第二种方法 - 但是你可能会引起很多皱眉......

Yes you are leaking, and the c++ way to do it is:

bool test = false;
test = true; 

// ta-da - no leak.

You could do the second approach - however you're likely to draw lots of frowning...

可遇━不可求 2024-12-05 20:49:40

是的,确实如此,您必须在覆盖地址之前删除。或者更好的是在堆栈上分配或使用智能指针。

Yes, exactly, you have to delete before you overwrite the address. Or better yet allocate on stack or use a smart pointer.

乞讨 2024-12-05 20:49:40

你确实是被宠坏了。

问题是您没有区分地址和变量。


bool *test = new bool(false);
  • test 分配自动持续时间的空间
  • 为 bool 分配动态持续时间的空间
  • false 写入此空间
  • 将此空间的地址存储到 test

test = new bool(true);
  • 分配具有 bool 动态持续时间的空间
  • true 写入此空间
  • 将此空间的地址存储到 test (之前存储的地址被无情地丢弃,因为它没有存储在其他任何地方,它指向的内存永远不可能回收,这意味着你有泄漏)。

delete test;
  • 读取test中存储的地址,
  • 释放该地址的空间

我的直觉告诉我第一个是正确的,因为指针测试指向内存中的同一地址,并且为其变量分配新值,不会更改该地址。或者 new 运算符是否在内存中分配不同的地址?

从语义上讲,您应该考虑 new 总是返回内存中 new 空间的地址(显然是错误的,因为内存被重用)。这就是为什么每次对 new 的调用都需要与delete调用相匹配。

因此,您的直觉是错误的,new 不会“仅仅”创建一个变量。如果您来自 Java,这可能确实令人震惊,并且您需要一个强大的教程来掌握编程的细节。

You have indeed been spoiled.

The problem is that you do not differentiate between an address and a variable.


bool *test = new bool(false);
  • Allocate space with automatic duration for test
  • Allocate space with dynamic duration for a bool
  • Write false into this space
  • Store the address of this space into test

test = new bool(true);
  • Allocate space with dynamic duration for a bool
  • Write true into this space
  • Store the address of this space into test (the address previously stored is ruthlessly discarded, since it is not stored anywhere else, the memory it points to can never be reclaimed, which means you have a leak).

delete test;
  • Read the address stored into test
  • Deallocate the space at this address

My gut feeling tells me the first is right, as the pointer test points at the same address in memory, and assigning a new value to its variable, will not change this address. Or does the new operator allocate a different address in memory?

Semantically, you should consider that new always return an address to a new space in memory (Obviously false, as memory is reused). This is why each call to new need to be matched by exactly one call to delete.

Therefore your gut feeling is wrong, new does not create "just" a variable. If you are coming from Java, this may be shocking indeed, and you'll need a strong tutorial to grasp the finer points of programming.

断桥再见 2024-12-05 20:49:40

是的,你正在泄漏内存。对于每个新建,都应该有一个后续的删除。如果您使用新地址覆盖指针,那么您将失去将分配与删除配对的机会。

Yes, you are leaking memory. For every new there should be a subsequent delete. If you overwrite a pointer with a new address then you lose the opportunity to pair the allocation with a delete.

冷︶言冷语的世界 2024-12-05 20:49:40

是的,你的第一个例子实际上是内存泄漏。 每次new的调用都必须有一个对delete的匹配调用(除非new失败)。

在 C++ 中,执行您似乎想要执行的操作的正常方法是简单地在本地声明 bool:

bool b = truel
b = false;

但是,如果您由于某种原因实际上需要动态分配,则有智能指针来管理内存,因此您不必担心关于调用delete。您可以查找 scoped_ptrunique_ptrshared_ptr

最后,C++ 拥有一个出色的标准库,可以处理许多可能的容器和算法,使您无需重新发明它们,也无需在各种情况下处理动态分配。

如果您认真学习 C++,我会从 SO C++ 书籍列表中挑选一本书籍并从头开始学习,而不是尝试将 Java 习惯用法转移到 C++(这不会很好地工作)。

Yes, your first example is actually leaking memory. Every call to new must have a matched call to delete (unless the new failed).

In C++ the normal way to do what you appear to be trying to do is to simply declare the bool locally:

bool b = truel
b = false;

If however you actually need dynamic allocation for some reason, there are smart pointers that manage the memory so you don't have to worry about calling delete. You can look up scoped_ptr, unique_ptr and shared_ptr.

Finally, C++ has a great standard library that handles many possible containers and algorithms, preventing you from having to reinvent them and saving you from having to deal with dynamic allocation in a wide variety of cases.

If you're serious about learning C++ I would pick out one of the books from the SO C++ book list and learn from the ground up rather than trying to transfer Java idioms to C++ (it just won't work well).

真心难拥有 2024-12-05 20:49:40

bool 是一种内置数据类型。为什么需要这样分配内存?您可以轻松地在堆栈上分配内存

bool is a built in datatype.Why do you need to allocate memory like that?You can easily allocate on stack

落墨 2024-12-05 20:49:40

是的,在第一种情况下你正在泄漏内存。第二种方法是正确的方法。在第一种情况下......

当您第二次调用 new 时,第一个分配超出范围,但仍然存在。在 Java 中,这很好,因为 GC 会为您清理它。然而,在 C++ 中,原始指针没有这样的方法。

每次对 new 的调用也必须在某个时刻调用 delete 。另外,删除指针后,将其设置为 null 或 0。这将防止您意外删除无效内存。

Yes, you are leaking memory in the first case. The second way is the proper way to do it. In your first case...

When you call new the second time, the first allocation goes out of scope, but still exists. In Java, this is fine because the GC will clean it up for you. However, in C++, there's no such way with raw spointers.

Each call to new must also have a call to delete at some point. Also, after you delete a pointer, set it to null or 0. This will prevent you from accidently deleting invalid memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文