[英]Why memset init partially?
我正在尝试通过memset
用 0 初始化一个int **a
。 但结果是某些项目不为零。
源代码
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int main()
{
int aSize = 3;
int **a = (int **)malloc(sizeof(int *)*aSize);
for (int i=0; i<aSize; i++) {
a[i]=(int *)malloc(sizeof(int)*aSize);
}
memset(a[0], 0, aSize*aSize*sizeof(int));
for (int i=0; i<aSize; i++) {
for (int j=0; j<aSize; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
}
Output
0 0 0
0 0 0
0 1610612736 0
更新 1
我正在尝试按照建议的两种方式使malloc
连续。 但是在方法2中,初始化数组时抛出了异常。
#include <stdio.h>
#include <stdlib.h>
#include <strings.h> // memset header changed
// method 1
int **a = malloc(sizeof(int *)*aSize);
for (int i=0; i<aSize; i++) {
a[i]=malloc(sizeof(int)*aSize);
memset(a[i], 0, aSize*sizeof(int));
}
for (int i=0; i<aSize; i++) {
for (int j=0; j<aSize; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
for (int i=0; i<aSize; i++) {
free(a[i]);
}
free(a);
// method 2
a = malloc(sizeof(int *)*aSize + sizeof(int)*aSize);
memset(a[0], 0, aSize*aSize*sizeof(int)); // Exception: EXC_BAD_ACCESS (code=1, address=0x1c)
除了惊人的侥幸之外,这不可能奏效:
memset(a[0], 0, aSize*aSize*sizeof(int));
您通过将指针向量分配给单独分配的行来模拟多维数组。 但是在上面的表达式中,您假设 memory 是线性的(全部分配在一块)。 memset
写入超出a[0]
行的末尾,导致未定义的行为。
正确的方法是遍历指针数组,并单独memset
每一行:
for (i = 0; i < aSize; i++)
memset(a[i], 0, aSize * sizeof a[i]);
这个memset
动作可以提升到分配行的原始循环中; 此外,可以使用calloc
代替malloc
以使memset
变得不必要。 (C 语言要求全零位 memory 模式在解释为int
或double
等数字类型时产生零值,因此使用 call 将数字calloc
初始化为零是安全的)
此外,标准 C 中没有<memory.h>
header。 自 1989 年 C 首次标准化之前, malloc
function 已在<stdlib.h>
中声明。
您的memset
行假设在您的第一个for
循环中创建的指针数组指向连续的memory - 也就是说,例如,您假设a[1]
将指向紧跟在a[0]
.
但是,不能保证会出现这种情况,碰巧的是,在您的某些情况下,这是正确的,但最终,在这个假设上工作会导致未定义的行为!
要纠正该问题,您应该分别初始化每个 memory 缓冲区; 最简单的方法是在创建每一个时这样做:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int main()
{
int aSize = 3;
int **a = (int **)malloc(sizeof(int *)*aSize);
for (int i=0; i<aSize; i++) {
a[i]=(int *)malloc(sizeof(int)*aSize);
memset(a[i], 0, aSize*sizeof(int)); // Set each buffer to all zeros here!
}
// memset(a[0], 0, aSize*aSize*sizeof(int)); // This will cause undefined behaviour
for (int i=0; i<aSize; i++) {
for (int j=0; j<aSize; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
}
随时要求进一步澄清和/或解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.