C++基础--类--深拷贝和浅拷贝

浅拷贝与深拷贝的坑

以下代码会触发断点invalid address。堆区的数据被free()的时候可能会出的坑。

#include <iostream>
#include <cstring>

using namespace std;
class Solution {
public:
    int id = 0;
    char* my_name;
    Solution(char name[]) {
        this->my_name = (char*)malloc(strlen(name) +1);
        strcpy_s(my_name, strlen(name) + 1, name);
    }
};


int main() {
    char a[] = "六六六六啊";
    Solution s = Solution(a);
    //构造器默认提供的复制拷贝只是简单的赋值,所以导致s和s1的my_name地址相同
    Solution s1 = Solution(s);

    free(s.my_name);
    //触发断点!!!!!
    free(s1.my_name);
}

这里使用了复制构造对s1进行初始化,Solution类中的my_name是一个指针,所以s中my_name指针的值也被简单的复制到了s1中。 至此,s和s1的my_name指针均指向同一个堆中地址,这个地址里存放着"六六六六啊"。之后free(s.my_name), 这片地址直接被释放,当free(s1.my_name),相当于在free一个野指针,至此发生错误。

解决方案:深拷贝,自己添加复制拷贝方法,在复制的时候重新分配一片新的地址:

#include <iostream>
#include <cstring>

using namespace std;
class Solution {
public:
    int id = 0;
    char* my_name;
    Solution(char name[]) {
        this->my_name = (char*)malloc(strlen(name) +1);
        strcpy_s(my_name, strlen(name) + 1, name);
    }
    //深拷贝,自己添加复制拷贝方法,在复制的时候重新分配一片新的地址
    Solution(const Solution& s) {
        my_name = (char*)malloc(strlen(s.my_name) +1);
        strcpy_s(my_name, strlen(s.my_name) + 1, s.my_name);
    }
};


int main() {
    char a[] = "六六六六啊";
    Solution s = Solution(a);
    //构造器默认提供的复制拷贝只是简单的赋值,所以导致s和s1的my_name地址相同
    Solution s1 = Solution(s);

    free(s.my_name);
    //正常运行
    free(s1.my_name);

}
posted @ 2020-12-09 08:00  lsxkugou  阅读(100)  评论(0编辑  收藏  举报