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

memmove移动二维double数组仅迁移半数数据的原因咨询

二维double数组内存移动的字节数问题解析

嘿,这个问题的核心在于你没搞清楚C语言里二维数组的内存存储布局,以及memmove这类内存操作函数是如何处理连续内存块的。我给你拆解一下关键逻辑:

1. 二维数组的内存是「行优先连续存储」

你定义的double Weights[wt][2],在内存里并不是像表格那样按列排列的,而是把每一行的所有元素连续存放,再接下一行的元素。比如wt=3时,内存顺序是:
Weights[0][0] → Weights[0][1] → Weights[1][0] → Weights[1][1] → Weights[2][0] → Weights[2][1]

也就是说,第一列的元素(Weights[i][0])之间并不是连续的,每两个第一列元素中间隔了一个第二列的元素(Weights[i][1])。

2. 为什么wt * sizeof(double)只能迁移半数数据?

假设你的需求是把第一列的所有wt个元素复制到第二列对应的位置,那用memmove(Weights[0]+1, Weights[0], wt * sizeof(double))就错了:

  • 这个调用会从Weights[0][0]开始,拷贝连续的wt个double(也就是wt*8字节,假设double为8字节)。
  • 但这些连续的double里,一半是第一列元素,一半是第二列元素(比如wt=169时,前84行的两个元素+第85行的第一个元素,总共169个)。
  • 拷贝到Weights[0][1]开始的位置后,只能覆盖第二列的前84个元素,剩下的第二列元素根本没被触及,所以你看到“仅能迁移约半数数组数据”。

3. 为什么加*2就能实现?

当你把字节数改成wt * 2 * sizeof(double)时,其实是拷贝了整个二维数组的所有元素(总共wt*2个double),从Weights[0][0]到Weights[wt-1][1]全部拷贝到Weights[0][1]开始的位置。

  • 虽然这会超出原数组的范围(属于未定义行为),但恰好让你看到Weights[0][0]的数据出现在Weights[0][1]里,同时其他行的第一列数据也被覆盖到了第二列位置(连续拷贝把所有元素整体移了一位)。

正确的实现方式

如果你只是想把每一行的第一个元素赋值给第二个元素,根本不需要用memmove,直接用循环更安全清晰:

for (int i = 0; i < wt; i++) {
    Weights[i][1] = Weights[i][0];
}

如果确实需要用内存操作函数,得针对列元素的非连续性处理,比如逐行拷贝单个元素:

for (int i = 0; i < wt; i++) {
    memmove(&Weights[i][1], &Weights[i][0], sizeof(double));
}

内容的提问来源于stack exchange,提问作者Brian Lafferry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:57:17