xcode 删除析构函数中的指针
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26716333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Deleting pointers in destructor
提问by Jokull Reynisson
I have some pointers that I allocate in the constructor of a class and then attempt to delete in its destructor:
我在类的构造函数中分配了一些指针,然后尝试在其析构函数中删除:
TileMap::TileMap(int x, int y) {
mapSize.x = x;
mapSize.y = y;
p_p_map = new Tile*[x];
for(int i = 0; i < x; i++) {
p_p_map[i] = new Tile[y];
}
randomize();
}
TileMap::~TileMap() {
for(int i = 0; i < mapSize.x; i++) {
delete p_p_map[i];
}
delete p_p_map;
}
void TileMap::randomize() {
for(int i = 0; i < mapSize.x; i++) {
for(int j = 0; j < mapSize.y; j++) {
p_p_map[i][j] = *new Tile(Tile::TileSize * i, Tile::TileSize * j, TileType::randomType());
}
}
}
At the end of the program the destructor is called to free the memory of the pointers I allocated, but when it reaches "delete p_p_map[i];" in the destructor, XCode informs me that the pointer was not allocated. I am new to C++, but I feel that I pretty explicitly allocated memory to the pointers in the randomize() function.
在程序结束时,析构函数被调用以释放我分配的指针的内存,但是当它到达“delete p_p_map[i];”时 在析构函数中,XCode 通知我未分配指针。我是 C++ 的新手,但我觉得我非常明确地为 randomize() 函数中的指针分配了内存。
What error am I making?
我犯了什么错误?
回答by uesp
You have to match delete
with new
and delete[]
with new[]
. Mixing one up with the other leads to issues. So if you do:
你一定要配合delete
使用new
,并delete[]
用new[]
。将一种与另一种混合会导致问题。所以如果你这样做:
p_p_map = new Tile*[x];
you have to delete it like:
你必须像这样删除它:
delete[] p_p_map;
and same with
和一样
delete[] p_p_map[i];
If you create something like:
如果你创建类似的东西:
pSomething = new Type;
then you delete it like:
然后你删除它:
delete pSomething;
回答by utnapistim
What error am I making?
我犯了什么错误?
A few:
一些:
First, as @uesp pointed out, you mismatch new and delete calls
首先,正如@uesp 指出的,你不匹配 new 和 delete 调用
Second, you are using the "memory leak operator":
其次,您正在使用“内存泄漏运算符”:
p_p_map[i][j] = *new Tile(Tile::TileSize * i, Tile::TileSize * j, TileType::randomType());
The construct new Tile(...)
allocates memory. Then, this memory (not stored anywhere) is dereferenced, and the result is assigned to p_p_map[i][j].
该构造new Tile(...)
分配内存。然后,该内存(未存储在任何地方)被取消引用,并将结果分配给 p_p_map[i][j]。
Because the pointer is not stored anywhere, it is leaked.
因为指针没有存储在任何地方,所以它被泄漏了。
Third, you are not respecting RAII. While this is not technically an error in itself, the way you write the code is unsafe, and in low memory conditions, you will get UB.
第三,你不尊重 RAII。虽然这本身在技术上不是错误,但您编写代码的方式是不安全的,并且在内存不足的情况下,您将获得 UB。
For example, here's what happens if you construct a Tile
instance with large values for x and y:
例如,如果您构造一个Tile
具有较大 x 和 y 值的实例,会发生以下情况:
TileMap::TileMap(int x, int y) { // e.g. (x = 1024 * 1024, y = 1024 * 1024 * 1024)
mapSize.x = x;
mapSize.y = y;
p_p_map = new Tile*[x]; // allocate 1049600 pointers block
for(int i = 0; i < x; i++) {
p_p_map[i] = new Tile[y]; // run out of memory (for example) half way through the loop
}
randomize();
}
Depending where your allocations fail, your constructor will not finish executing, meaning your TileMap
instance is "half-constructed" (i.e. in an invalid state) and the destructor will not be called.
根据您的分配失败的位置,您的构造函数将不会完成执行,这意味着您的TileMap
实例是“半构造的”(即处于无效状态)并且不会调用析构函数。
In this case, everything the class allocated is leaked, and (especially if you allocated a large size) your application is left in low memory conditions.
在这种情况下,分配的类的所有内容都会泄漏,并且(特别是如果您分配了较大的大小)您的应用程序将处于低内存状态。
To fix this, make sure each pointer is managed by a different instance of a class (part of RAII). This ensures that if an allocation fails, the allocated resources are released before exitting the scope, as part of stack unwinding (as @CaptainObvlious said, use std::vector for the array and std::unique_ptr for each element).
要解决此问题,请确保每个指针都由类的不同实例(RAII 的一部分)管理。这确保如果分配失败,则在退出范围之前释放分配的资源,作为堆栈展开的一部分(如@CaptainObvlious 所说,对数组使用 std::vector,对每个元素使用 std::unique_ptr)。