调用memset会导致分段错误

时间:2013-05-28 13:40:55

标签: c unix struct segmentation-fault memset

此程序在我的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;
}

3 个答案:

答案 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_dirnew_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);