C++结构体指针传递未实现深拷贝,输出不符合预期该如何解决
问题根因
- 你的代码首先没有执行任何拷贝逻辑:C++函数参数默认是值传递,传入的
a1、a2都是指针的副本,函数内执行node1 = node2仅修改了局部副本的指向,外层a1仍然指向最初new出来的、number为0的节点,和a2完全无关,自然输出0。 - C++不存在“传递指针自动深拷贝”的机制,直接对指针赋值仅会复制内存地址,属于浅拷贝。要实现深拷贝必须手动编写逻辑,复制结构体所有成员,包括递归拷贝左右子节点的完整内容,而不是只复制子节点的指针。
修复方案
首先需要实现通用的节点深拷贝函数,再根据需求选择对应的修改方式:
#include <iostream> using namespace std; struct node{ int number = 0; struct node* right_child = NULL; struct node* left_child = NULL; }; // 通用深拷贝函数,完整复制节点的所有内容 node* deep_copy_node(const node* source) { if (source == NULL) return NULL; node* new_node = new node; new_node->number = source->number; // 递归深拷贝左右子节点 new_node->left_child = deep_copy_node(source->left_child); new_node->right_child = deep_copy_node(source->right_child); return new_node; }
方案1:拷贝内容到a1已分配的内存空间
适合a1已经提前分配内存的场景,直接把a2的内容覆盖到a1的内存地址上:
void test(struct node* node1 , const struct node* node2){ if (node1 == NULL || node2 == NULL) return; node1->number = node2->number; // 先释放原有子节点内存避免泄漏 delete node1->left_child; delete node1->right_child; // 深拷贝子节点 node1->left_child = deep_copy_node(node2->left_child); node1->right_child = deep_copy_node(node2->right_child); } int main(){ struct node* a1 = new struct node; struct node* a2 = new struct node; a2->number = 3; test(a1 , a2); cout << a1->number; // 输出3 // 用完释放内存避免泄漏 delete a1; delete a2; return 0; }
方案2:修改外层a1的指向,让它直接指向深拷贝出来的新节点
如果不需要保留a1原来的内存空间,可以把test第一个参数改成指针的引用,让函数内修改指针的操作可以影响外层的a1:
// 第一个参数为指针的引用,修改会同步到外层 void test(struct node*& node1 , const struct node* node2){ // 先释放原有内存避免泄漏 delete node1; node1 = deep_copy_node(node2); } // main函数不需要修改,运行后同样输出3
注意事项
- 深拷贝必须完整复制所有层级的动态内存内容,不能直接对指针做赋值操作,否则两个指针会指向同一块内存,后续释放时会出现重复释放的崩溃问题。
- 动态申请的内存用完后要手动
delete释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Alireza Arbabi
相关产品推荐
相关产品推荐

