C++ - 使用“new”在堆上分配内存
如果我有以下语句:
int *x = new int;
在这种情况下,我已经在堆上动态分配了内存。换句话说,我现在有一个 int
对象的保留
内存地址。
之后说我做了以下操作:
delete x;
这意味着我释放了
堆上的内存地址。
之后我再次执行了以下操作:
int *x = new int;
将 x
指向它所指向的相同旧内存地址删除之前的堆?
如果我在删除之前执行此操作:
x = NULL;
然后执行此操作:
int *x = new int;
将会x
指向堆上不同于旧地址的内存地址?
谢谢。
If I have the following statement:
int *x = new int;
In this case, I have allocated memory on the heap dynamically. In other words, I now have a reserved
memory address for an int
object.
Say after that that I made the following:
delete x;
Which means that I freed up
the memory address on the heap.
Say after that I did the following again:
int *x = new int;
Will x
point to the same old memory address it pointed to at the heap before it was deleted?
What if I did this before delete
:
x = NULL;
And, then did this:
int *x = new int;
Will x
point to a a memory address on the heap other than the old one?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在第一种情况下,您可能会再次获得相同的内存块,但这并不确定。
在第二种情况下,由于您尚未释放内存,因此几乎可以肯定您会在不同的地址获得不同的内存块。 C++ 有垃圾收集器。如果您使用其中之一,则可以想象垃圾收集器将在您将指针置空(因此您不再有权访问先前分配的内存块)和再次请求分配之间运行。在这种情况下,您可以再次获得相同的内存块。当然,如果没有垃圾收集器,您只会泄漏内存,因此无论如何您都无法这样做。
In the first case, you might get the same block of memory again, but there's no certainty of it.
In the second case, since you haven't freed the memory, there's a near-certainty that you'll get a different block of memory at a different address. There are garbage collectors of C++. If you used one of these, it's conceivable that the garbage collector would run between the time you NULLed out the pointer (so you no longer had access to the previously-allocated memory block) and asking for an allocation again. In such a case, you could get the same memory block again. Of course, without a garbage collector, you're just leaking memory, so you don't way to do this in any case.
您所要求的完全是未定义的(根据 C/C++ 标准),并且取决于实现。
您应该很容易使用您的编译器版本来测试这一点。
但您应该注意的是,永远不要依赖此行为的结果,因为它可以随时/随任何操作系统/甚至升级编译器而改变。
至于我认为可能发生的情况,你很可能会得到相同的地址,除非你的程序中有其他线程也在同一时间进行分配。但即使如此,如果编译器的特定 malloc 实现决定对不同线程使用不同的堆(这在性能方面更好),您也可能会获得相同的地址
What you are asking is entirely undefined (as per C/C++ standard) and would depend on the implementation.
it should be easy for you to test this out with your version of the compiler.
What you should note though is to never depend on the outcome of this behavior as it can change any time / with any os / even an upgrade to your compiler.
As to what i think might happen, you would get the same address most likely, UNLESS you have other threads in your program which are also allocating during the same time. But even then you might get the same address, if the particular malloc implementation of your compiler decides to use different heaps for different threads (which is better in terms of perf)
当您在删除之前执行此操作时:
则这是内存泄漏。你失去了没有任何用处的内存,而且你无法释放它,因为你失去了它的地址。 (您可以删除空指针,它什么也不做)
这样做太多时间可能会导致系统崩溃/速度减慢到可接受的程度,因为所有内存都被浪费了。 (在磁盘上使用交换太多等等...等等...)
不要期望在删除后获得相同的确切新地址,然后再次获得新地址。尽管它可能会不时地、随机地发生。
When you do this before delete:
then it is a memory leak. You lose memory that serves nothing, and that you cant free because you lost the address of it. (you can delete a null pointer, it just does nothing)
Doing this too much time can result in a system crash / slowing down more that acceptable because all your memory is wasted. (using swap on disk too much etc... etc...)
Dont expect to get the same exact new address after a delete, then a new again. Though it may happen from time to time, randomly.
不,没有这样的保证。这完全取决于用于满足您的内存请求的分配器。然而,C++ 是一个强大的野兽,让我们重写 new 运算符。您可以构建一个自定义分配器(内存管理),它以某种方式提供内存,这有时非常有用。
No, there's no such guarantee. This depends entirely on the allocator used to satisfy your memory request. However, C++ being the powerful beast that it is, let's you override the new operator. You can build a custom allocator (memory managment) which provide memory in a certain manner, which sometimes is very useful.
不,从第二个 new int; 返回的指针可以指向有效可写地址范围内的任何位置。无法保证之前释放的区域会被使用(事实上,大多数时候可能不会,因为堆管理器可能会选择在稍后的某个时间点释放实际内存)。
No, the pointer returned from second
new int;
can point anywhere within the valid writable address reange. There is no guarantee that the previously deallocated region will be used (in fact most of the times it may not as the heap manager may choose to release the actual memory at some later point of time).1)释放后,如果使用相同的变量再次分配,则不能保证您将获得相同的内存块。想想 new 是如何实现的,它可以用任何你能想象的方式来完成,甚至使用自定义分配器。另外,其他线程可能在 free() 和 new() 调用之间使用了 new 并“窃取”了您的内存
2)不要这样做。您正在丢失引用,如果您对 NULL 指针应用删除运算符,它将不会执行任何操作。因此,如果您不将引用存储在其他变量上,则可能会出现资源泄漏。如果你再次调用 new ,它肯定会在其他地方分配,假设没有人释放第一个 new() 授予的区域
1) After you free, if you allocate again using the same variable there is no guarantee you are going to get the same chunk of memory. Think about how new is implemented, it can be done any way you can imagine even using custom allocators. Also, it's possible that other thread used new between free() and new() calls and 'stole' your memory
2) Don't do it. You are losing reference and if you apply delete operator on NULL pointer it will do nothing. So you might have a resource leak if you don't store the reference on other variable. If you call new again it will definately allocate somewhere else assuming that noone deallocated the area granted by first new()