字符串数组C的分段错误

我创建了一个程序,将一个字符串分成由空格分隔的标记,然后将每个单独的字符串复制到一个字符串数组中。

程序运行正常,直到它达到for循环,并在成功将第一个字符串添加到数组并打印它之后,程序崩溃。 我调试了它,发现了

args[i] = malloc((strlen(comm_str) + 1) * sizeof(char)); 

返回SEGFAULT然后第二次执行循环。 同样调用堆栈打印出以下内容:

地址:75F943F9,function:strlen(),文件:C:\ Windows \ syswow64 \ msvcrt.dll。

我试图自己纠正程序,但没有结果。 我一开始认为循环尝试访问超出绑定区域,但我认为我已正确地对所有内容进行了malloc。

 #include  #include  #include  int main(){ char **args = NULL; char input[] = "cmdline -s 20 -r -t parameter -p 20 filename"; int num = 0; char *comm_str = strtok(input, " "); /*Tokens command line*/ while(comm_str != NULL){ /*Counts number of tokens*/ num++; printf("%s %d\n", comm_str, strlen(comm_str)); comm_str = strtok(NULL, " "); } printf("\n"); args = malloc(num * sizeof(char*)); /*Allocates memory for the first string entry*/ if(!args){ return 0; } comm_str = strtok(input, " "); /*Starts tokening from beginning*/ for(int i = 0; i < num; i++){ args[i] = malloc((strlen(comm_str) + 1) * sizeof(char)); /*Allocates memory for strings*/ if(!args[i]){ for(int b = 0; b < i; b++){ free(args[b]); } free(args); return 0; } strcpy(args[i], comm_str); printf("%s\n", args[i]); comm_str = strtok(NULL, " "); } printf("%d\n", num); } 

正如你所知, strtok正在改变字符串。

计算单词数后,该字符串将包含一个单词。 因此,下一个strtok将返回NULL。

以非破坏性方式计算参数数量,或制作字符串的副本。

根据strtok的手册页:“使用这些函数时要小心。如果你使用它们,请注意:这些函数修改它们的第一个参数。这些函数不能用于常量字符串。”

因此,第一次解析找到num时,修改输入字符串,因此第二次解析垃圾时会导致SEGFAULT。 此外,您不应该使用常量字符串:

 char input[] = "cmdline -s 20 -r -t parameter -p 20 filename"; 

第一个问题是您没有包含相关的函数原型。 这将使它假设一切都是整数。 见下文:

 $ gcc -Wall xc -ox xc: In function 'main': xc:9:5: warning: implicit declaration of function 'strtok' [-Wimplicit-function-declaration] xc:9:22: warning: initialization makes pointer from integer without a cast [enabled by default] xc:13:9: warning: implicit declaration of function 'strlen' [-Wimplicit-function-declaration] xc:13:37: warning: incompatible implicit declaration of built-in function 'strlen' [enabled by default] xc:13:9: warning: format '%d' expects argument of type 'int', but argument 3 has type 'long unsigned int' [-Wformat] xc:14:18: warning: assignment makes pointer from integer without a cast [enabled by default] xc:18:5: warning: implicit declaration of function 'malloc' [-Wimplicit-function-declaration] xc:18:12: warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default] xc:23:14: warning: assignment makes pointer from integer without a cast [enabled by default] xc:24:5: error: 'for' loop initial declarations are only allowed in C99 mode xc:24:5: note: use option -std=c99 or -std=gnu99 to compile your code xc:25:27: warning: incompatible implicit declaration of built-in function 'strlen' [enabled by default] xc:27:13: error: 'for' loop initial declarations are only allowed in C99 mode xc:28:17: warning: implicit declaration of function 'free' [-Wimplicit-function-declaration] xc:28:17: warning: incompatible implicit declaration of built-in function 'free' [enabled by default] xc:30:13: warning: incompatible implicit declaration of built-in function 'free' [enabled by default] xc:33:9: warning: implicit declaration of function 'strcpy' [-Wimplicit-function-declaration] xc:33:9: warning: incompatible implicit declaration of built-in function 'strcpy' [enabled by default] xc:35:18: warning: assignment makes pointer from integer without a cast [enabled by default] xc:40:1: warning: control reaches end of non-void function [-Wreturn-type] 

我建议你在继续之前解决这个问题。

在你的情况下, strtokNULL替换每个' ' 。 考虑以下:

 char input[] = "cmdline -s 20 -r -t parameter -p 20 filename"; size_t inputSize = strlen(input); for(int i = 0; i < inputSize; i++) printf("%02X ", input[i]); printf("\n\n"); char *comm_str = strtok(input, " "); while(comm_str != NULL) comm_str = strtok(NULL, " "); for(int i = 0; i < inputSize; i++) printf("%02X ", input[i]); printf("\n\n"); 

输出:

 63 6D 64 6C 69 6E 65 20 2D 73 20 32 30 20 2D 72 20 2D 74 20 70 61 72 61 6D 65 74 65 72 20 2D 70 20 32 30 20 66 69 6C 65 6E 61 6D 65 

 63 6D 64 6C 69 6E 65 00 2D 73 00 32 30 00 2D 72 00 2D 74 00 70 61 72 61 6D 65 74 65 72 00 2D 70 00 32 30 00 66 69 6C 65 6E 61 6D 65