I read the previous questions on dynamic arrays in C however I was not able to relate the answers to my question.
I am taking commands from stdin
using fgets, removing the newline character and then want to store each command delimited by a space in a dynamically allocated array of strings. I however am having a lot of trouble with the correct way to allocated and reallocate memory. I am compiling with clang
and keep getting segmentation fault 11. I then used -fsanitize=address
and keep getting:
==2286==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eeb8 at pc 0x000108fb6f85 bp 0x7fff56c49560 sp 0x7fff56c49558 WRITE of size 8 at 0x60200000eeb8 thread T0
Here is my code:
// Sets a delimiter to split the input
const char *seperator = " ";
char *token = strtok(line, seperator);
char **cmds = (char **) malloc(sizeof(char) * sizeof(*cmds));
// Adds first token to array of delimited commands
cmds[0] = token;
int count = 1;
while (token != NULL) {
token = strtok(NULL, sep);
if (token != NULL) {
cmds = (char **) realloc(cmds, sizeof(char) * (count + 1));
// Adds next token array of delimited commands
cmds[count] = token;
count++;
}
}
You're not allocating enough memory. cmds
is an array of pointers, so each element is sizeof(char *)
bytes, not sizeof(char)
bytes.
On the initial allocation you want 1 char *
, then on subsequent allocations you want count + 1
.
Also, don't cast the return value of malloc
, as that can hide other problems, and don't forget to check for failures.
char **cmds = malloc(sizeof(char *) * 1);
if (cmds == NULL) {
perror("malloc failed");
exit(1);
}
...
cmds = realloc(cmds, sizeof(char *) * (count + 1));
if (cmds == NULL) {
perror("reallocfailed");
exit(1);
}