Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.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++_Arrays_Memory_Delete Operator - Fatal编程技术网

C++ 如何释放动态结构数组的内存

C++ 如何释放动态结构数组的内存,c++,arrays,memory,delete-operator,C++,Arrays,Memory,Delete Operator,作为一个从未处理过释放内存等问题的人,我的任务是创建一个结构的动态数组,并创建函数来添加或删除数组元素。删除时,我必须释放不再需要的内存 删除大小为3的数组的第二个元素时,我将第三个元素移动到第二个位置,然后删除最后一个元素。当删除最后一个时,我总是得到一个错误。。。有人能为我找到解决办法吗 struct myFriend { myFriend() { number=0; hobbys = new char*[10]; } int numb

作为一个从未处理过释放内存等问题的人,我的任务是创建一个结构的动态数组,并创建函数来添加或删除数组元素。删除时,我必须释放不再需要的内存

删除大小为3的数组的第二个元素时,我将第三个元素移动到第二个位置,然后删除最后一个元素。当删除最后一个时,我总是得到一个错误。。。有人能为我找到解决办法吗

struct myFriend {
    myFriend() {
        number=0;
        hobbys = new char*[10];
    }
    int number;
    char* name;
    char** hobbys;
};
int main() {
    myFriend* friendList = new myFriend[10];

    myFriend* tempFriend = new myFriend;
    tempFriend->number=1;
    tempFriend->name = "ABC";

    myFriend* tempFriend2 = new myFriend;
    tempFriend2->number=2;
    tempFriend->name = "XYZ";

    myFriend* tempFriend3 = new myFriend;
    tempFriend3->number=3;
    tempFriend3->name = "123";

    friendList[0] = *tempFriend;
    friendList[1] = *tempFriend2;
    friendList[2] = *tempFriend3;

    friendList[1] = friendList[2]; //move 3rd element on 2nd position
    delete &(friendList[2]); //and delete 3rd element to free memory
}

为什么要创建临时变量?甚至不需要它们

如果使用
std::vector
std::string
,您面临的问题将自动消失:

std::vector<myFriend> friendList(10);

friendList[0]->number=1;
friendList[0]->name = "ABC";

friendList[1]->number=2;
friendList[1]->name = "XYZ";

friendList[2]->number=3;
friendList[2]->name = "123";
如果您执行以下任一操作,则它将是错误的,并将调用未定义的行为:

delete friends[2];    //wrong
delete &(friends[2]); //wrong

为什么要创建临时变量?甚至不需要它们

如果使用
std::vector
std::string
,您面临的问题将自动消失:

std::vector<myFriend> friendList(10);

friendList[0]->number=1;
friendList[0]->name = "ABC";

friendList[1]->number=2;
friendList[1]->name = "XYZ";

friendList[2]->number=3;
friendList[2]->name = "123";
如果您执行以下任一操作,则它将是错误的,并将调用未定义的行为:

delete friends[2];    //wrong
delete &(friends[2]); //wrong

数组大小固定为10,因此不需要从中删除任何元素。但是您确实需要删除
好友列表[1]
中的
名称
霍布斯
元素(在覆盖之前)。这里有两个问题:

  • 您正在设置
    friendList[0]->name=“ABC”“ABC”
    是内存中某个以零结尾的常量字符串。不允许您删除它。所以你必须复制一份
  • 无论何时分配爱好[i],您都要删除它。但是在你的代码中,你无法分辨它是否被分配。因此,必须将构造函数中的每个元素都设置为0,以便以后知道要删除哪些元素
    删除这些元素的正确位置是myFriends的析构函数。

    数组大小固定为10,因此不需要从中删除任何元素。但是您确实需要删除
    好友列表[1]
    中的
    名称
    霍布斯
    元素(在覆盖之前)。这里有两个问题:

  • 您正在设置
    friendList[0]->name=“ABC”“ABC”
    是内存中某个以零结尾的常量字符串。不允许您删除它。所以你必须复制一份
  • 无论何时分配爱好[i],您都要删除它。但是在你的代码中,你无法分辨它是否被分配。因此,必须将构造函数中的每个元素都设置为0,以便以后知道要删除哪些元素
    删除这些元素的正确位置是
    myFriends
    的析构函数。

    无法从
    new[]分配的数组中删除子集。

    myFriend*friendList=newmyfriend[10]

    你有一个完整的数组

    +------------------------------------------------------------------+
    |  friendList[0]  |  friendList[1]  |    .....  |   friendList[9]  | 
    +------------------------------------------------------------------+
    
    您不能
    删除&(好友列表[2])
    。 您可以从
    C++
    获得10个元素的整个数组。 此数组从
    好友列表
    (或
    &(好友列表[0])
    )开始

    operator delete
    ,其指针指向
    new
    (即
    friendList
    )返回的地址是有效的
    仅限。

    无法从
    new[]分配的数组中删除子集。

    myFriend*friendList=newmyfriend[10]

    你有一个完整的数组

    +------------------------------------------------------------------+
    |  friendList[0]  |  friendList[1]  |    .....  |   friendList[9]  | 
    +------------------------------------------------------------------+
    
    您不能
    删除&(好友列表[2])
    。 您可以从
    C++
    获得10个元素的整个数组。 此数组从
    好友列表
    (或
    &(好友列表[0])
    )开始

    operator delete
    ,其指针指向
    new
    (即
    friendList
    )返回的地址是有效的
    只有。

    问题的关键似乎是管理动态数组。主要的问题是他使用的是一个朋友列表数组。使用指向好友列表的指针数组:

    struct myFriend {
        myFriend() {
            number=0;
            hobbys = new char*[10];
        }
        int number;
        char* name;
        char** hobbys;
    };
    int main() {
        myFriend** friendList = new myFriend*[10];
    
        myFriend* tempFriend = new myFriend;
        tempFriend->number=1;
        tempFriend->name = "ABC";
    
        myFriend* tempFriend2 = new myFriend;
        tempFriend2->number=2;
        tempFriend->name = "XYZ";
    
        myFriend* tempFriend3 = new myFriend;
        tempFriend3->number=3;
        tempFriend3->name = "123";
    
        friendList[0] = tempFriend;
        friendList[1] = tempFriend2;
        friendList[2] = tempFriend3;
    
        friendList[1] = friendList[2]; //move 3rd element on 2nd position
        delete friendList[2]; //and delete 3rd element to free memory
    }
    

    但其他人都是对的——关于“霍布斯”和“名字”的内存分配,存在着一些主要问题,需要分别进行分类。

    问题的关键似乎是管理一个动态数组。主要的问题是他使用的是一个朋友列表数组。使用指向好友列表的指针数组:

    struct myFriend {
        myFriend() {
            number=0;
            hobbys = new char*[10];
        }
        int number;
        char* name;
        char** hobbys;
    };
    int main() {
        myFriend** friendList = new myFriend*[10];
    
        myFriend* tempFriend = new myFriend;
        tempFriend->number=1;
        tempFriend->name = "ABC";
    
        myFriend* tempFriend2 = new myFriend;
        tempFriend2->number=2;
        tempFriend->name = "XYZ";
    
        myFriend* tempFriend3 = new myFriend;
        tempFriend3->number=3;
        tempFriend3->name = "123";
    
        friendList[0] = tempFriend;
        friendList[1] = tempFriend2;
        friendList[2] = tempFriend3;
    
        friendList[1] = friendList[2]; //move 3rd element on 2nd position
        delete friendList[2]; //and delete 3rd element to free memory
    }
    

    但其他人都是对的——关于“hobbys”和“name”的内存分配有一些主要问题,需要分别加以解决。

    要做作业,我建议您学习更多关于指针、新/删除运算符、新[]/delete[]运算符(不要与新/删除运算符混淆)和对象创建/复制/构造函数/析构函数。它是基本C++特性,你的任务是关于这个的。 要指出一些方向:

    1) 当您像这样动态地分配对象时

    MyType* p = new MyType;
    
    MyType* p = new MyType[n];
    

    获取指向已创建对象的指针(
    new
    为类型为
    MyType
    的单个对象分配内存,并调用该对象的构造函数)

    在完成对该对象的操作后,必须调用

    delete p;
    
    delete[] p;  // not "delete p;"
    
    delete
    调用对象的析构函数,然后释放内存。如果不调用
    delete
    ,内存就会泄漏。如果您多次调用它,则行为是未定义的(可能是堆损坏,这可能导致程序崩溃—有时是在非常奇怪的时刻)

    2) 当您像这样动态分配数组时

    MyType* p = new MyType;
    
    MyType* p = new MyType[n];
    
    将指针
    p
    指向按顺序位于内存中的
    n
    创建对象的数组(
    new[]
    n
    类型的
    MyType
    对象分配单个内存块,并为每个对象调用默认构造函数)

    无法更改此动态数组中的元素数。您只能删除它。 使用该数组的工作完成后,必须调用

    delete p;
    
    delete[] p;  // not "delete p;"
    
    delete[]
    调用数组中每个对象的析构函数,然后释放m