Reputation: 732
I know where the segmentation fault happens, but can't see why.
My principal function is like this:
int execute_line(char *line){
char **arguments;
int i = parse_args(arguments,line); //separates line in arguments
printf("Number of tokens: %d \n",i); //prints number of total tokens
printf("%s\n",arguments[0]); //print first token so I know it's not void
int r = check_internal(arguments); //segmentation fault
}
While the parse_args function fills arguments like:
int parse_args(char **args, char *line){
const char s[]= " \t\n\r";
char *token;
token = strtok(line, s);//separates line with the separators
int i=0;
char null[] = "(null)";
while( token != NULL ) {
if (token[0]=='#'){ //if the like begins with "comment" I don't care
args[i]=null;
return i;
}else{
args[i] = token;// else fills each char * of **args with a token
printf("Parse_args()--> token %d: ",i);
printf("%s\n",token);
i++;
}
token = strtok(NULL, s); //separates again
}
args[i]=null; //ends with null
return i;
}
I can't see why it gives segmentation fault as my prints after parse_args returns the tokens correctly (so **arguments is filled at least) but when I call int r = check_internal(arguments); It gives me segmentation fault, (If I put a print in the first line of my function it does not show, so I suppose that's the breakpoint (print debug ftw)).
Can anyone point me where I'm missing the pointer to a correct part of memory?
Error: Segmentation fault (core dumped)
check_internal: int check_internal(char **args);
If my input is :
hey ho letsgo
the program returns:
Parse_args()--> token 0: hey
Parse_args()--> token 1: ho
Parse_args()--> token 2: letsgo
Number of tokens: 3
hey
Segmentation fault (core dumped)
Thank you to anyone that can help me :D
Upvotes: 0
Views: 249
Reputation: 225387
When you call parse_args
, arguments
is not initialized. Then inside of parse_args
, you dereference this uninitialized pointer when you assign to args[i]
. Doing so invokes undefined behavior, which in this caes manifests as a crash.
Declare arguments
as an array of pointers large enough for your purposes:
char *arguments[100];
Or, if you don't know how many arguments you'll have you can instead pass the address of a char **
and dynamically allocate memory for it as you read in the arguments:
int parse_args(char ***args, char *line){
const char s[]= " \t\n\r";
char *token;
token = strtok(line, s);//separates line with the separators
int i=0;
char null[] = "(null)";
*args = malloc(1 * sizeof(char *));
while( token != NULL ) {
if (token[0]=='#'){ //if the like begins with "comment" I don't care
(*args)[i]=null;
return i;
}else{
(*args)[i] = token;// else fills each char * of **args with a token
printf("Parse_args()--> token %d: ",i);
printf("%s\n",token);
i++;
}
*args = realloc(*args, i * sizeof(char *));
token = strtok(NULL, s); //separates again
}
(*args)[i]=null; //ends with null
return i;
}
And call it like this:
char **arguments;
int i = parse_args(&arguments,line);
Upvotes: 2