-1

The function makearg is supposed to count the number of words in a char array and also break each word up into their own spot in a pointer array. Segmentation fault seems to be a problem with the strncpy function.

int makearg(char s[], char ***args);

int main(){

  char **args = (char**)(malloc(100));

  char *str = "ls is a -l file";
  int argc;
  argc = makearg(str, &args);

  printf("%d", argc);
  printf("%c", '\0');

  int i;
  for(i = 0; i < argc; i++){
    puts(args);
    printf("%c", '\n');
  }
  return 0;
}

/////////////////////////////////////////

int makearg(char s[], char ***args){

  int argc = 0;
  int charc = 0;
  int wordstart = 0;

  while(1){
    if(s[charc] == '\0'){
      strncpy(*args[argc], s + wordstart, charc - wordstart);
      args[argc][(charc - wordstart) + 1] = '\0';

      argc++;
      break;
  }

  if(s[charc] == ' '){
    strncpy(*args[argc], s + wordstart, charc - wordstart);
    args[argc][(charc -  wordstart) + 1] = '\0';

    wordstart = charc + 1;
    argc++;
    charc++;
  }

  else{
    charc++;
    }
  }
  return argc;
}
  • 1)`char **args = (char**)malloc(100*sizeof(char*));` 2)args[index] is not initialize(memory area need for store by strncpy). 3)`*args[argc],` --> `(*args)[argc],` when `char ***args;` – BLUEPIXY Sep 11 '14 at 23:33
  • 4)`puts(args);` --> `puts(args[i]);` 5)`args[argc][(charc - wordstart) + 1] = '\0';` --> `args[argc][charc - wordstart] = '\0';` – BLUEPIXY Sep 11 '14 at 23:39
  • 6)`int makearg(char s[], char ***args){` : No need for triple pointer because it is not rewritten. 7) `printf("%c", '\0');` no meaning – BLUEPIXY Sep 11 '14 at 23:46
  • @BLUEPIXY write an answer – M.M Sep 12 '14 at 05:45
  • @Eric what was `printf("%c", '\0');` trying to achieve – M.M Sep 12 '14 at 05:46
  • Increase the warning level of your compiler and tell it to treat warnings as errors. – pmg Sep 12 '14 at 08:08

2 Answers2

1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int makearg(const char s[], char ***args);

int main(void){
    char **args = NULL;
    const char *str = "ls is a -l file";
    int argc = makearg(str, &args);

    printf("argc : %d\n", argc);

    int i;
    for(i = 0; i < argc; i++){
        puts(args[i]);
        free(args[i]);
    }
    free(args);
    return 0;
}

int wordCount(const char *s){
    char prev = ' ';
    int wc = 0;

    while(*s){
        if(isspace(prev) && !isspace(*s)){
            ++wc;
        }
        prev = *s++;
    }
    return wc;
}

int makearg(const char s[], char ***args /*out*/){
    int argc = wordCount(s);
    int len;

    if(argc == 0){
        *args = NULL;
        return 0;
    }
    *args = malloc(argc * sizeof(char*));
    argc = 0;
    while(1){
        while(isspace(*s))
            ++s;
        if(EOF==sscanf(s, "%*s%n", &len))
            break;
        (*args)[argc] = malloc(len + 1);
        strncpy((*args)[argc], s, len);
        (*args)[argc++][len] = '\0';
        s += len;
    }
    return argc;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0

You allocated space for the args array of pointers, but you never allocate space for the strings you intend to store in them, so when you try to store the strings in makearg, you are interpreting whatever random garbage is there as a pointer, and that's not going to work.

Also, you only allocate 100 bytes for the pointer array -- it's not clear how many words you expect to be able to split, but the malloc call should probably look more like

char **args = malloc(MAX_WORDS * sizeof(char *));  /* no cast required */

then follow that with a loop to do MAX_WORDS more malloc calls, in order to initialize args with valid pointers.

Jim Lewis
  • 43,505
  • 7
  • 82
  • 96
  • when allocating memory like this, it isn't allocated in ROM right? I am still getting a segfault when i add the null character to each word – Eric Gallegos Sep 12 '14 at 01:47
  • The malloc call [should not have a cast](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – M.M Sep 12 '14 at 05:45