此程序在我的UNIX计算机上导致seg错误。我将原因缩小到memset()的第二次调用。
为什么会出现这种情况?第一个" chunk"代码几乎与第二个相同,不是吗?如果第二个问题,为什么没有对memset segfault进行第一次调用呢?
我查看了有关segfaulting memset调用的其他线程,但没有一个类似于此。
如果您想知道为什么我写了这么简单的程序,那么它改编自我正在编写的另一个程序,我用它来教自己如何将memcpy()应用于结构。
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int x;
char text;
} FilesStruct;
int
main(int argc, char** argv)
{
FilesStruct *old_dir;
memset(old_dir,0,sizeof(FilesStruct));
old_dir->x = 3;
old_dir->text = 'c';
printf("old dir: %d,%c\n",old_dir->x,old_dir->text);
FilesStruct *new_dir;
memset(new_dir,0,sizeof(FilesStruct));
new_dir->x = 7;
new_dir->text = 'g';
printf("new dir: %d,%c\n",new_dir->x,new_dir->text);
return 0;
}
答案 0 :(得分:10)
FilesStruct *old_dir;
memset(old_dir,0,sizeof(FilesStruct));
尝试写入未初始化的指针。这会导致未定义的行为,包括可能发生的崩溃。它只是运气(好或坏,取决于你如何看待它),这种行为的第一个实例没有崩溃。
您需要为old_dir
分配内存。最简单的方法是在堆栈中声明它
FilesStruct old_dir;
memset(&old_dir,0,sizeof(old_dir));
或者您可以在堆上动态分配(确保在不再需要对象时调用free
)
FilesStruct *old_dir = calloc(1, sizeof(*old_dir);
/* use old_dir */
free(old_dir);
这同样适用于代码中的new_dir
。
答案 1 :(得分:3)
old_dir
和new_dir
都未初始化,因此这是未定义的行为。一种解决方案是在堆栈上分配两个变量:
FilesStruct old_dir;
//...
FilesStruct new_dir;
并在调用&
时使用memset
运算符获取地址:
memset(&old_dir,0,sizeof(FilesStruct));
答案 2 :(得分:3)
FilesStruct *old_dir;
这定义了一个FilesStruct指针。它是未初始化的,因此它实际上并不指向FilesStruct的任何存储。
memset(old_dir,0,sizeof(FilesStruct));
告诉memset将old_dir指向的内容归零,但是当指针未初始化时,你会得到未定义的行为。
您需要为指针提供存储空间,例如
FilesStruct *old_dir = malloc(sizeof(FilesStruct));
在您的情况下,您可能不需要指针或动态分配的内存,您可以
FilesStruct old_dir;
memset(&old_dir,0,sizeof(FilesStruct));
old_dir.x = 3;
old_dir.text = 'c';
printf("old dir: %d,%c\n",old_dir.x,old_dir.text);