简体   繁体   中英

What is the difference between char *var= NULL; and char var[LENGTH + 1];?

I am creating a function to load a Hash Table and I'm getting a segmentation fault if my code looks like this

bool load(const char *dictionary)
{
    // initialize vars
    char *line = NULL;
    size_t len = 0;
    unsigned int hashed;

    //open file and check it
    FILE *fp = fopen(dictionary, "r");
    if (fp == NULL)
    {
        return false;
    }

    while (fscanf(fp, "%s", line) != EOF)
    {
        //create node
        node *data = malloc(sizeof(node));
        //clear memory if things go south
        if (data == NULL)
        {
            fclose(fp);
            unload();
            return false;
        }

        //put data in node
        //data->word = *line;
        strcpy(data->word, line);

        hashed = hash(line);
        hashed = hashed % N;

        data->next = table[hashed];
        table[hashed] = data;
        dictionary_size++;
    }

    fclose(fp);
    return true;
}

However If I replace

char *line = NULL; by char line[LENGTH + 1]; (where length is 45)

It works. What is going on aren't they "equivalent"?

They are not equivalent.

In the first case char *line = NULL; you have a pointer-to- char which is initialised to NULL . When you call fscanf() it tries to write data to it and this will cause it to dereference the NULL pointer. Hence segfault.

One option to fix that would have been to allocate ( malloc() and friends) the required memory first, check the pointer is not NULL (allocation failed) before using it. Then you would need to free() the resources once you no longer need the data.

In the second case char line[LENGTH +1] you have an array-of- char of size LENGTH + 1 . This memory has been allocated for you on the stack (the compiler ensures this happens automatically for arrays), and the memory is only 'valid' for use during the lifetime of the function: once you return you must no longer use it. Now, when you pass the pointer to fscanf() (to the first element of the array in this case), fscanf() has a memory buffer to write to. As long as the buffer is large enough to hold the data being written this works correctly.

When you do fscanf(fp, "%s", line) it'll try to read data into the memory pointed to by line - but char *line = NULL; does not allocate any memory.

When you do char line[LENGTH + 1]; you allocate an array of LENGTH + 1 char s.

Note that if a word in the file is longer than LENGTH your program will write out of bounds. Always use bounds checking operations.

Example:

while (fscanf(fp, "%*s", LENGTH, line) != EOF)
char *line = NULL;

Says "I want a variable named 'line' that can point to characters, but is not currently pointing to anything." The compiler will allocate memory that can hold a memory address, and will fill it with zero (or some other internal representation of "points to nothing").

char line[10];

Says "allocate memory for 10 characters, and I would like to use the name 'line' for the address of the first one". It does not allocate space to hold the memory address, because that's a constant, but it does allocate space for the characters (and does not initialize them).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM