B
benjamin sago
Hello all. I am writing a command shell, but am having trouble with
memory allocations. I am trying to tokenise a string into a **char
array for execvp (the unix launch-this-program function), but I get
segmentation faults when I run it.
Here is the code that I use to parse the string, which fails:
char buf[] = "abcde fghij klmno"; /* sample string */
int arg = 0, pos = 0, i, in_string = 0;
char **args = NULL;
args = malloc(1 + sizeof(char *));
if (args == NULL) { printf("malloc failed"); exit(1); }
for (i = 0; buf; i++) {
char c = buf;
/* Space -> move on to the next argument */
if (c == ' ' && pos != 0 && in_string == 0) {
arg++; /* next argument */
args[arg] = (char *) realloc(args, pos + 1);
args[arg][0] = '\0';
pos = 0;
args = (char **) realloc(args, arg * sizeof(char *));
/* add another line */
if (args == NULL) { printf("realloc failed (1)");
exit(1); }
continue;
}
/* Quotes -> toggle being in a string */
if (c == '"') {
in_string = !in_string;
continue;
}
/* backslash -> skip a character */
if (c == '\\') c = buf[++i];
/* Anything else -> add to the args list */
args[arg] = realloc(args, (pos) * sizeof(char) + 1); /* resize
to fit the new character */
if (args[arg] == NULL) { printf("realloc failed (2)"); exit(1);
}
args[arg][pos] = c;
args[arg][pos+1] = '\0'; /* so it is a null-terminated string
*/
pos++;
}
The length of **args should be increasing to fit whatever I try to put
in it, but it is not.
It parses the first letter fine, but segfaults on the second. Sometimes
it likes the second letter too, but segfaults on the third. I ran it
through the gnu debugger, and it always faults on the line
"args[arg][pos+1] = '\0';", so I am thinking that I am not allocating
enough, or allocating in the wrong place.
What is wrong?
memory allocations. I am trying to tokenise a string into a **char
array for execvp (the unix launch-this-program function), but I get
segmentation faults when I run it.
Here is the code that I use to parse the string, which fails:
char buf[] = "abcde fghij klmno"; /* sample string */
int arg = 0, pos = 0, i, in_string = 0;
char **args = NULL;
args = malloc(1 + sizeof(char *));
if (args == NULL) { printf("malloc failed"); exit(1); }
for (i = 0; buf; i++) {
char c = buf;
/* Space -> move on to the next argument */
if (c == ' ' && pos != 0 && in_string == 0) {
arg++; /* next argument */
args[arg] = (char *) realloc(args, pos + 1);
args[arg][0] = '\0';
pos = 0;
args = (char **) realloc(args, arg * sizeof(char *));
/* add another line */
if (args == NULL) { printf("realloc failed (1)");
exit(1); }
continue;
}
/* Quotes -> toggle being in a string */
if (c == '"') {
in_string = !in_string;
continue;
}
/* backslash -> skip a character */
if (c == '\\') c = buf[++i];
/* Anything else -> add to the args list */
args[arg] = realloc(args, (pos) * sizeof(char) + 1); /* resize
to fit the new character */
if (args[arg] == NULL) { printf("realloc failed (2)"); exit(1);
}
args[arg][pos] = c;
args[arg][pos+1] = '\0'; /* so it is a null-terminated string
*/
pos++;
}
The length of **args should be increasing to fit whatever I try to put
in it, but it is not.
It parses the first letter fine, but segfaults on the second. Sometimes
it likes the second letter too, but segfaults on the third. I ran it
through the gnu debugger, and it always faults on the line
"args[arg][pos+1] = '\0';", so I am thinking that I am not allocating
enough, or allocating in the wrong place.
What is wrong?