0
votes

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

1
char **arguments; int i = parse_args(arguments,line); => arguments isn't initialized: undefined behaviour. Or is there some code you're not showing?Jean-François Fabre♦
yep, you never allocated args in parse_args.Matthieu Brucher
but if I initialitze it at char **arguments=NULL, it doesn't even get to show anything and it directly shows Segmentation fault (core dumped). How can I initialitze it without giving it space as I don't know how big can the input be?flaixman

1 Answers

2
votes

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);