【问题标题】:Segmentation fault when parsing c string into pointer array将 c 字符串解析为指针数组时出现分段错误
【发布时间】:2014-09-11 23:24:01
【问题描述】:

函数 makearg 应该计算 char 数组中的单词数,并将每个单词分解为指针数组中它们自己的位置。 分段错误似乎是 strncpy 函数的问题。

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] 未初始化(内存区域需要由 strncpy 存储)。 3)*args[argc], --> (*args)[argc],char ***args;
  • 4)puts(args); --> puts(args[i]); 5)args[argc][(charc - wordstart) + 1] = '\0'; --> args[argc][charc - wordstart] = '\0';
  • 6)int makearg(char s[], char ***args){ :不需要三重指针,因为它没有被重写。 7)printf("%c", '\0');没有意义
  • @BLUEPIXY 写一个答案
  • @Eric printf("%c", '\0'); 试图达到什么目的

标签: c arrays pointers segmentation-fault


【解决方案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;
}

【讨论】:

    【解决方案2】:

    您为args 指针数组分配了空间,但您从未为要存储在其中的字符串分配空间,因此当您尝试将字符串存储在makearg 中时,您正在解释任何随机垃圾那里作为一个指针,这是行不通的。

    另外,您只为指针数组分配了 100 个字节——不清楚有多少 您希望能够拆分的单词,但 malloc 调用可能看起来更像

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

    然后使用循环执行 MAX_WORDS 个更多 malloc 调用,以便使用有效指针初始化 args

    【讨论】:

    • 这样分配内存时,不是在ROM中分配的吧?当我将空字符添加到每个单词时,我仍然遇到段错误
    • malloc 调用should not have a cast
    猜你喜欢
    • 2015-03-25
    • 2021-11-21
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    相关资源
    最近更新 更多