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.