Reputation: 303
This is part of my program. parameters.path
is a string that contains a path to the file I will be working with, but that is not in this code.
typedef struct directory {
char *name;
char *path;
} directory;
void insertDir(directory*** array , char * path, char* name, int* length) {
directory *p = malloc(sizeof(directory));
p->path = malloc(strlen(path)+ 1);
strcpy(p->path, path);
p->name = malloc(strlen(name)+ 1);
strcpy(p->name, name);
*array = (directory**) realloc( *array , (*length) * (sizeof(directory*)));
*array[(*length)] = p;
(*length)++;
}
int main(int argc , char** argv) {
directory** array = NULL;
int lenght = 0;
while(true) {
insertDir(&array, parameters.path, name , &lenght);
}
return 0;
}
It fails on the third realloc
with segmentation fault. Can you help me please?
Upvotes: 1
Views: 11009
Reputation: 84561
In addition to the (*array)[*length]
indexing issue, you leave yourself wide open for several allocation failures with both malloc
and realloc
. First, and generally, always validate that your allocation succeeds. Enough said.
Next, with realloc
, it is always better to reallocate using a temporary
variable instead of your array. If there is a failure on reallocation, realloc
returns NULL
causing you to lose the address to array
completely. This will cause the loss of all existing data. Instead, if you use a tmp
pointer for reallocation, you have the ability to handle the failure in a graceful manner, and the ability to free
the block of memory originally assigned to array
.
Here is a bit more robust way to handle the allocations/reallocations. Note: you are left to code the response to a reallocation failure:
void insertDir (directory*** array, char *path, char *name, int *length)
{
directory *p = malloc (sizeof *p);
if (!p) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
p->path = malloc (strlen (path) + 1);
strcpy (p->path, path);
p->name = malloc (strlen (name) + 1);
strcpy(p->name, name);
directory **tmp = realloc (*array, (*length + 1) * sizeof *tmp);
if (!tmp) {
fprintf (stderr, "error: struct reallocation failure.\n");
exit (EXIT_FAILURE);
}
*array = tmp;
(*array)[*length] = p;
(*length)++;
}
Upvotes: 3
Reputation: 780974
When doing the realloc()
, you need to add 1 to the length, because you haven't incremented it yet.
*array = realloc( *array , (*length + 1) * (sizeof(directory*)));
You also need to change:
*array[(*length)] = p;
to:
(*array)[*length] = p;
because the subscripting operator has higher precedence than the dereference operator. See the C operator precedence table here. There's also no need for parentheses inside []
.
Upvotes: 6