作者gowrite (gowrite)
看板C_and_CPP
标题[问题] 2D 阵列之记忆体位址有移位情形
时间Sun May 2 07:10:22 2021
开发平台(Platform): (Ex: Win10, Linux, ...)
GNU/Linux
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
GCC
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
N/A
问题(Question):
印象中,
阵列不管是几维的,记忆体位址应该是连续分布,
但实际上有规则性跳跃的情况
想问各位,这样的行为有专有名词吗?
谢谢
喂入的资料(Input):
请看下方程式码
预期的正确结果(Expected Output):
预期 二维阵列 在 row 0 到 row 1 时,
记忆体的位址也是连续,
但实际上展现出来是会跳跃 找 0 尾数为 下一个 row 的开头
错误结果(Wrong Output):
无错误,想知道是编译器的问题,还是 C 语言的正常规格行为
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
int row = 2;
int col = 3;
// 建立 二维 int 阵列
int **arr = malloc(sizeof(int *) * row);
for(int i=0 ; i<row ; i++){
arr[i] = malloc(sizeof(int) * col);
}
// 填入数值
for(int i=0 ; i<row ; i++){
for(int j=0 ; j<col ; j++){
arr[i][j] = i+ ((j+1)*2);
}
}
当 row = 2, col = 3 时
row :0, col :0, arr[0][0] = 2, 0x55963ccf92c0
row :0, col :1, arr[0][1] = 4, 0x55963ccf92c4
row :0, col :2, arr[0][2] = 6, 0x55963ccf92c8
row :1, col :0, arr[1][0] = 3, 0x55963ccf92e0
row :1, col :1, arr[1][1] = 5, 0x55963ccf92e4
row :1, col :2, arr[1][2] = 7, 0x55963ccf92e8
可以看到 row 1 跟 row 2 中间从 92c8 跳到了 92e0 多跳了 4 bytes
当 row = 2, col = 4 时
row :0, col :0, arr[0][0] = 2, 0x55b7ab0542c0
row :0, col :1, arr[0][1] = 4, 0x55b7ab0542c4
row :0, col :2, arr[0][2] = 6, 0x55b7ab0542c8
row :0, col :3, arr[0][3] = 8, 0x55b7ab0542cc
row :1, col :0, arr[1][0] = 3, 0x55b7ab0542e0
row :1, col :1, arr[1][1] = 5, 0x55b7ab0542e4
row :1, col :2, arr[1][2] = 7, 0x55b7ab0542e8
row :1, col :3, arr[1][3] = 9, 0x55b7ab0542ec
这样就正常
当 row = 2, col = 5 时
row :0, col :0, arr[0][0] = 2, 0x55eea8bac2c0
row :0, col :1, arr[0][1] = 4, 0x55eea8bac2c4
row :0, col :2, arr[0][2] = 6, 0x55eea8bac2c8
row :0, col :3, arr[0][3] = 8, 0x55eea8bac2cc
row :0, col :4, arr[0][4] = 10, 0x55eea8bac2d0
row :1, col :0, arr[1][0] = 3, 0x55eea8bac2e0
row :1, col :1, arr[1][1] = 5, 0x55eea8bac2e4
row :1, col :2, arr[1][2] = 7, 0x55eea8bac2e8
row :1, col :3, arr[1][3] = 9, 0x55eea8bac2ec
row :1, col :4, arr[1][4] = 11, 0x55eea8bac2f0
居然从 c2d0 多跳了 12 个 bytes 硬是跳到 c2e0 开头
补充说明(Supplement):
N/A
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 118.171.199.9 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1619910624.A.69C.html
1F:推 LPH66: 因为你并不是为底层结构配置连续记忆体 (你的 for/malloc) 05/02 07:44
2F:→ LPH66: 也就是说, 对系统来说你的每一列都是个别一块记忆体 05/02 07:45
3F:→ LPH66: 因此它们之间就并不一定有什麽位置上的关系了 05/02 07:45
4F:→ LPH66: 会在附近只是因为刚好那附近都还没人用而已 05/02 07:46
5F:→ LPH66: 要配置成连续的也不是不行, 但就不是 for/malloc 一列一列 05/02 07:47
6F:→ LPH66: 要, 而是一口气要来一整块之後指定每一列进列指标阵列 05/02 07:47
7F:→ LPH66: 另外, cc 到 e0 没有连续喔, 中间还有 d 05/02 07:51
8F:→ F04E: 你是配置了复数个一维阵列而不是一个二维... 05/02 08:29
9F:推 stupid0319: malloc二维阵列应该是for loop malloc多个一维阵列 05/02 09:25
10F:推 stupid0319: 编译器没问题,C语言也没问题,单纯只是写法bug 05/02 09:28
11F:→ stupid0319: 写code怀疑编译器有问题的,我是头一个看到......... 05/02 09:30
12F:推 xam: code写错,怀疑编译器/程式语言/电脑有错的人,很多啊 05/02 12:11
13F:推 millaker0820: 正确写法应该是先malloc一个大小为row*col的连续记 05/02 17:48
14F:→ millaker0820: 忆体,在一一把pointer指向每个row的开头 这样就会 05/02 17:48
15F:→ millaker0820: 是连续的了 05/02 17:48
16F:→ Lipraxde: 很有想法 ! 05/02 21:19
17F:→ cuteSquirrel: 一楼专业 05/03 10:29
18F:推 chchwy: 你呼叫了好多次malloc() 这样当然没有保证连续 05/03 11:17
19F:推 Qbsuran: 就算是一次分配 阵列只有1D/2D "刚好"连续 05/04 18:26