You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何锯齿数组逐行调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:35:26