字符串数组C的分段错误
我制作了一个程序,该程序将一个字符串拆分为以空格分隔的标记,然后将每个单独的字符串复制到一个字符串数组中 程序工作正常,直到到达for循环,并且在成功地将第一个字符串添加到数组并打印后,程序崩溃。我调试后发现字符串数组C的分段错误,c,arrays,string,segmentation-fault,C,Arrays,String,Segmentation Fault,我制作了一个程序,该程序将一个字符串拆分为以空格分隔的标记,然后将每个单独的字符串复制到一个字符串数组中 程序工作正常,直到到达for循环,并且在成功地将第一个字符串添加到数组并打印后,程序崩溃。我调试后发现 args[i] = malloc((strlen(comm_str) + 1) * sizeof(char)); 返回SEGFAULT,然后第二次执行循环。另外,调用堆栈打印出以下内容: 地址:75F943F9,函数:strlen(),文件:C:\Windows\syswow64\msv
args[i] = malloc((strlen(comm_str) + 1) * sizeof(char));
返回SEGFAULT
,然后第二次执行循环。另外,调用堆栈打印出以下内容:
地址:75F943F9,函数:strlen(),文件:C:\Windows\syswow64\msvcrt.dll`
我试图自己修改程序,但没有结果。起初我以为循环会尝试访问越界区域,但我认为我已经正确地处理了所有问题
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
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);
}
#包括
#包括
#包括
int main(){
字符**args=NULL;
字符输入[]=“cmdline-s 20-r-t参数-p 20文件名”;
int num=0;
char*comm_str=strtok(输入“”);/*Tokens命令行*/
而(comm_str!=NULL){/*统计令牌数*/
num++;
printf(“%s%d\n”,comm_str,strlen(comm_str));
comm_str=strtok(空,“”);
}
printf(“\n”);
args=malloc(num*sizeof(char*);/*为第一个字符串条目分配内存*/
如果(!args){
返回0;
}
comm_str=strtok(输入“”);/*从一开始就开始标记*/
for(int i=0;i
strtok
正如您所知,正在更改字符串
计算字数后,字符串将包含一个单词。因此,下一个strtok将返回NULL
以非破坏性的方式计算参数的数量,或复制字符串。第一个问题是您没有包含相关的函数原型。这将使它假设一切都是整数。见下文:
$ gcc -Wall x.c -o x
x.c: In function ‘main’:
x.c:9:5: warning: implicit declaration of function ‘strtok’ [-Wimplicit-function-declaration]
x.c:9:22: warning: initialization makes pointer from integer without a cast [enabled by default]
x.c:13:9: warning: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]
x.c:13:37: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
x.c:13:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat]
x.c:14:18: warning: assignment makes pointer from integer without a cast [enabled by default]
x.c:18:5: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
x.c:18:12: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
x.c:23:14: warning: assignment makes pointer from integer without a cast [enabled by default]
x.c:24:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
x.c:24:5: note: use option -std=c99 or -std=gnu99 to compile your code
x.c:25:27: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
x.c:27:13: error: ‘for’ loop initial declarations are only allowed in C99 mode
x.c:28:17: warning: implicit declaration of function ‘free’ [-Wimplicit-function-declaration]
x.c:28:17: warning: incompatible implicit declaration of built-in function ‘free’ [enabled by default]
x.c:30:13: warning: incompatible implicit declaration of built-in function ‘free’ [enabled by default]
x.c:33:9: warning: implicit declaration of function ‘strcpy’ [-Wimplicit-function-declaration]
x.c:33:9: warning: incompatible implicit declaration of built-in function ‘strcpy’ [enabled by default]
x.c:35:18: warning: assignment makes pointer from integer without a cast [enabled by default]
x.c:40:1: warning: control reaches end of non-void function [-Wreturn-type]
我建议您在继续之前解决此问题。根据strtok手册: “使用这些功能时要小心。如果确实使用了这些功能,请注意: 这些函数修改它们的第一个参数。 这些函数不能用于常量字符串。” 因此,第一次解析find num时,修改输入字符串,第二次解析垃圾时也是如此,这会导致SEGFAULT。此外,不应使用常量字符串:
char input[] = "cmdline -s 20 -r -t parameter -p 20 filename";
strtok
在您的案例中,将每个'
替换为NULL
。考虑以下事项:
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");
char input[]=“cmdline-s 20-r-t参数-p 20文件名”;
大小\u t输入大小=strlen(输入);
for(int i=0;i
输出:
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
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 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
“返回SEGFULT then[…]”-再次出现?您可能忘记正确分配内存。args[0…num-1]也应为malloc'd。“然后返回SEGFAULT…”听起来不太对劲。我认为
then
是一个拼写错误,当@vpit3833他在malloc时得到SEGFAULT。不,然后I=0,循环执行没有问题,并打印出“cmdline”,但之后(I=1)在'args[I]=malloc((strlen(comm_str)+1)*sizeof(char));'SEGFAULT发生了。我已经包含了#include、#include和#include,我的编译器没有返回任何警告。明白了!我不知道strtok会修改原始字符串,但现在我已经制作了它的第二个副本,for循环可以按预期工作。谢谢你的帮助。