Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在析构函数中删除指针_C++_Xcode_Macos_Pointers - Fatal编程技术网

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
而不是自己管理内存,会让你受益匪浅。听起来你没有遵循,如果你坚持用受虐狂的方式管理动态对象,这很容易被打破