C++ 在析构函数中删除指针
我在类的构造函数中分配了一些指针,然后尝试在其析构函数中删除这些指针:C++ 在析构函数中删除指针,c++,xcode,macos,pointers,C++,Xcode,Macos,Pointers,我在类的构造函数中分配了一些指针,然后尝试在其析构函数中删除这些指针: 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::~Ti
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());
}
}
}
TileMap::TileMap(intx,inty){
mapSize.x=x;
mapSize.y=y;
p_p_map=新瓷砖*[x];
对于(int i=0;i
在程序结束时调用析构函数以释放我分配的指针的内存,但当它到达析构函数中的“delete p_p_map[I];”时,XCode通知我指针未分配。我是C++新手,但我觉得我很清楚地把内存分配给了RealdIsIe()函数中的指针。
我犯了什么错误?您必须将
delete
与new
匹配,并将delete[]
与new[]
匹配。把一个和另一个混为一谈会导致问题。因此,如果你这样做:
p_p_map = new Tile*[x];
您必须删除它,如下所示:
delete[] p_p_map;
delete pSomething;
同样的
delete[] p_p_map[i];
如果您创建以下内容:
pSomething = new Type;
然后删除它,如下所示:
delete[] p_p_map;
delete pSomething;
您必须将
delete
与new
匹配,将delete[]
与new[]
匹配。把一个和另一个混为一谈会导致问题。因此,如果你这样做:
p_p_map = new Tile*[x];
您必须删除它,如下所示:
delete[] p_p_map;
delete pSomething;
同样的
delete[] p_p_map[i];
如果您创建以下内容:
pSomething = new Type;
然后删除它,如下所示:
delete[] p_p_map;
delete pSomething;
我犯了什么错误
一些:
首先,正如@uesp所指出的,您不匹配new和delete调用
其次,您正在使用“内存泄漏操作符”:
构造new Tile(…)
分配内存。然后,该内存(不存储在任何地方)被取消引用,结果被分配给p_p_map[i][j]
因为指针没有存储在任何地方,所以它会泄漏
第三,你不尊重莱伊。虽然从技术上讲,这本身并不是一个错误,但编写代码的方式是不安全的,在内存不足的情况下,您将得到UB
例如,如果为x和y构建一个具有大值的Tile
实例,会发生以下情况:
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();
}
TileMap::TileMap(intx,inty){//例如(x=1024*1024,y=1024*1024)
mapSize.x=x;
mapSize.y=y;
p_p_map=new Tile*[x];//分配1049600个指针块
对于(int i=0;i
根据分配失败的位置,构造函数将不会完成执行,这意味着TileMap
实例是“半构造的”(即处于无效状态),并且不会调用析构函数
在这种情况下,类分配的所有内容都会泄漏,并且(特别是如果分配了较大的大小)应用程序的内存不足
要解决这个问题,请确保每个指针都由一个类的不同实例(RAII的一部分)管理。这确保了如果分配失败,在退出作用域之前释放分配的资源,作为堆栈展开的一部分(正如@CaptainObvlious所说,对数组使用std::vector,对每个元素使用std::unique_ptr)
我犯了什么错误
一些:
首先,正如@uesp所指出的,您不匹配new和delete调用
其次,您正在使用“内存泄漏操作符”:
构造new Tile(…)
分配内存。然后,该内存(不存储在任何地方)被取消引用,结果被分配给p_p_map[i][j]
因为指针没有存储在任何地方,所以它会泄漏
第三,你不尊重莱伊。虽然从技术上讲,这本身并不是一个错误,但编写代码的方式是不安全的,在内存不足的情况下,您将得到UB
例如,如果为x和y构建一个具有大值的Tile
实例,会发生以下情况:
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();
}
TileMap::TileMap(intx,inty){//例如(x=1024*1024,y=1024*1024)
mapSize.x=x;
mapSize.y=y;
p_p_map=new Tile*[x];//分配1049600个指针块
对于(int i=0;i
根据分配失败的位置,构造函数将不会完成执行,这意味着TileMap
实例是“半构造的”(即处于无效状态),并且不会调用析构函数
在这种情况下,类分配的所有内容都会泄漏,并且(特别是如果分配了较大的大小)应用程序的内存不足
要解决这个问题,请确保每个指针都由一个类的不同实例(RAII的一部分)管理。这确保了如果分配失败,在退出作用域之前释放分配的资源,作为堆栈展开的一部分(正如@CaptainObvlious所说,对数组使用std::vector,对每个元素使用std::unique_ptr).使用
std::vector
和std::unique\u ptr
/boost::unique\u ptr
或std::shared\u ptr
/boost::shared\u ptr
而不是自己管理内存,会让您受益匪浅。听起来您没有遵循,如果你坚持通过强迫改变原始指针来管理动态对象,这很容易被打破。使用std::vector
。使用std::vector
和std::unique_ptr
/boost::unique_ptr
或std::shared_ptr
/boost::shared_ptr
而不是自己管理内存,会让你受益匪浅。听起来你没有遵循,如果你坚持用受虐狂的方式管理动态对象,这很容易被打破