为何锯齿数组逐行调用ToArray()是深拷贝,直接调用是浅拷贝?
锯齿数组深拷贝与浅拷贝的差异原因
在处理算法问题时,需要将输入数据存入graph和meltedGraph两个锯齿数组(int[][]类型),代码实现如下:
int[] nm = Array.ConvertAll(Console.ReadLine().Split(),int.Parse); int[][]graph = new int[nm[0]][]; int[][] meltedGraph = new int[nm[0]][]; for (int i = 0; i < nm[0]; i++) { graph[i] = Array.ConvertAll(Console.ReadLine().Split(), int.Parse); // 深拷贝 meltedGraph[i] = graph[i].ToArray(); } // 浅拷贝 //meltedGraph = graph.ToArray();
对应的输入示例:
5 7 0 0 0 0 0 0 0 0 2 4 5 3 0 0 0 3 0 2 5 2 0 0 7 6 2 4 0 0 0 0 0 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0
循环逐行对graph的每行调用ToArray()赋值给meltedGraph时实现了深拷贝,但直接对graph调用ToArray()赋值给meltedGraph却仅为浅拷贝,原因如下:
核心本质:锯齿数组是「数组的数组」
int[][]类型的锯齿数组,本质是存储引用的数组——外层数组的每个元素都是指向另一个int[](子数组)的引用,而非直接存储数值。
1. 循环逐行调用ToArray()实现深拷贝的逻辑
graph[i]是一个int[]类型的子数组,调用ToArray()方法时,会创建一个全新的int[]数组,并把原graph[i]里的所有数值逐一复制到新数组中。- 将这个新数组的引用赋值给
meltedGraph[i]后,meltedGraph的每个子数组都和graph的对应子数组完全独立。修改任意一个数组的子数组元素,都不会影响另一个数组,这就是深拷贝。
2. 直接调用graph.ToArray()仅实现浅拷贝的逻辑
graph是外层的int[][]数组,调用ToArray()方法时,只会创建一个全新的外层数组,但新数组里的每个元素(即子数组的引用)都是直接复制原graph外层数组里的引用。- 也就是说,
meltedGraph和graph的外层数组是两个不同的数组,但它们内部的子数组是完全共享的。比如修改meltedGraph[1][1]的值,graph[1][1]也会跟着变化,因为二者指向同一个子数组,这就是浅拷贝。
内容的提问来源于stack exchange,提问作者Mint
相关产品推荐
相关产品推荐

