Calling memset causes segmentation fault

18,623

Solution 1

FilesStruct *old_dir;
memset(old_dir,0,sizeof(FilesStruct));

attempts to write to an uninitialised pointer. This results in undefined behaviour, including possibly a crash. Its just luck (good or bad, depending on how you look at it) that the first instance of this behaviour didn't crash.

You need to allocate memory for old_dir. The easiest way to do this is to declare it on the stack

FilesStruct old_dir;
memset(&old_dir,0,sizeof(old_dir));

or you could dynamically allocate on the heap (making sure to call free when you no longer need the object)

FilesStruct *old_dir = calloc(1, sizeof(*old_dir);
/* use old_dir */
free(old_dir);

The same applies to new_dir further down your code.

Solution 2

FilesStruct *old_dir;

This defines a FilesStruct pointer. It is uninitialized, so it doesn't actually point to any storage for a FilesStruct.

memset(old_dir,0,sizeof(FilesStruct));

Will tell memset to zero out whatever old_dir points at, but as the pointer is uninitialized, you get undefined behavior.

You'll need to provide storage for your pointer, e.g.

FilesStruct *old_dir = malloc(sizeof(FilesStruct));

In your case you don't really need a pointer or dynamically allocated memory, you might do

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);

Solution 3

Neither old_dir nor new_dir are initialized, so this is undefined behavior. One solution would be to allocate both variables on the stack:

FilesStruct old_dir;
//...
FilesStruct new_dir;

and use the & operator to obtain the address when calling memset:

memset(&old_dir,0,sizeof(FilesStruct));
Share:
18,623
python_newbie
Author by

python_newbie

Software Engineering student at the University of Melbourne.

Updated on June 04, 2022

Comments

  • python_newbie
    python_newbie almost 2 years

    This program causes a seg fault on my UNIX machine. I narrowed the cause down to the second call of memset().

    Why is this behaviour occurring? The first "chunk" of code is almost the same as the second, isn't it? Why didn't the first call of memset segfault if the second one does?

    I looked over other threads concerning segfaulting memset calls, but none of them were similar to this.

    In case you were wondering why I wrote such a trivial program, it's adapted from another program I've been writing that I was using to teach myself how to apply memcpy() to structures.

    #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;
    }
    
  • python_newbie
    python_newbie almost 11 years
    Oh, I was intending to use memset as an initialiser, guess I got that quite wrong. So my declaration only declares a pointer, but not the underlying structure; hence, I need to allocate memory before memsetting to 0?
  • simonc
    simonc almost 11 years
    @Noob Yes, that's it exactly