C 例外的原因是什么?
有人能找出错误的原因吗? 代码如下C 例外的原因是什么?,c,windows,C,Windows,有人能找出错误的原因吗? 代码如下 #include <stdio.h> #include <conio.h> #include <string.h> int main(int argc, char *argv[]){ strcat(argv[1], ", Agniva welcomes you"); printf("%s", argv[1]); getch(); return 0; } 但如果我通过命令行获取一个不需要的额
#include <stdio.h>
#include <conio.h>
#include <string.h>
int main(int argc, char *argv[]){
strcat(argv[1], ", Agniva welcomes you");
printf("%s", argv[1]);
getch();
return 0;
}
但如果我通过命令行获取一个不需要的额外参数,那么这个错误就会消失。你能说出是哪一个造成了这个问题吗?strcat(argv[1],“,Agniva欢迎你”)代码>
这正是原因所在-首先,您只能在以下情况下访问argv[1]
:
if (argc > 1) // do something with argv[1]
第二,即使argv[1]
指向有效的内存块-您只需用strcat
覆盖它-将数据附加到它。在您的具体案例中,从堆中分配argv[1]
,并将其大小写入内存块。因此,您得到的堆已损坏。strcat(argv[1],“,Agniva欢迎您”)代码>
这正是原因所在-首先,您只能在以下情况下访问argv[1]
:
if (argc > 1) // do something with argv[1]
第二,即使argv[1]
指向有效的内存块-您只需用strcat
覆盖它-将数据附加到它。在您的具体案例中,从堆中分配argv[1]
,并将其大小写入内存块。因此,您得到的堆已损坏。这是我之前对该问题的评论,几乎是一个完整的答案
简言之,argv中没有为每个项分配额外的内存空间,因此当您尝试在其上strcat更多字符串时,您是在缓冲区外写入,这会导致未定义的行为。当您提供了一个额外的参数时,实际上您正在写入另一个参数所在的内存。同样,这是特定于实现的,当您在另一个平台(如Linux)上运行程序时,可能仍然会出现未定义的行为。这是我之前对这个问题的评论,几乎是一个完整的答案
简言之,argv中没有为每个项分配额外的内存空间,因此当您尝试在其上strcat更多字符串时,您是在缓冲区外写入,这会导致未定义的行为。当您提供了一个额外的参数时,实际上您正在写入另一个参数所在的内存。同样,这是特定于实现的,当您在另一个平台(如Linux)上运行该程序时,可能仍然会出现未定义的行为。您无法知道为argv[1]分配了多少内存,但仍试图用另外20多个字节对其进行存根
strcat(argv[1], ", Agniva welcomes you");
也许是这样的
if( argc < 2 )
return -1;
char *oBuf = calloc( strlen( argv[1] ) + 25 /* for this ", Agniva welcomes you" */ , 1);
sprintf( oBuf, "%s%s",argv[1], ", Agniva welcomes you");
printf("%s", oBuf);
return 0;
if(argc<2)
返回-1;
char*oBuf=calloc(strlen(argv[1])+25/*为此,“Agniva欢迎您”*/,1);
sprintf(oBuf,“%s%s”,argv[1],“Agniva欢迎您”);
printf(“%s”,oBuf);
返回0;
您无法知道为argv[1]分配了多少内存,但仍试图用另外20多个字节对其进行存根
strcat(argv[1], ", Agniva welcomes you");
也许是这样的
if( argc < 2 )
return -1;
char *oBuf = calloc( strlen( argv[1] ) + 25 /* for this ", Agniva welcomes you" */ , 1);
sprintf( oBuf, "%s%s",argv[1], ", Agniva welcomes you");
printf("%s", oBuf);
return 0;
if(argc<2)
返回-1;
char*oBuf=calloc(strlen(argv[1])+25/*为此,“Agniva欢迎您”*/,1);
sprintf(oBuf,“%s%s”,argv[1],“Agniva欢迎您”);
printf(“%s”,oBuf);
返回0;
欢迎来到!你好像迷路了。那很好。我已经投票将这个问题迁移到,在那里你可以得到专业的答案,这也是这个问题的正确位置。谢谢您的理解。@iBug大多数在这里发布编程问题的人这样做是因为他们在so上被禁止提问,这将导致迁移失败。因此,除非有特殊原因,我通常不会尝试迁移,例如,有人已经回答了这里,如果我们不迁移,答案将丢失。@DanHulme鉴于我编辑的内容质量和正确的格式,这一次可能值得一试。如果你愿意,我将不胜感激。谢谢,欢迎光临!你好像迷路了。那很好。我已经投票将这个问题迁移到,在那里你可以得到专业的答案,这也是这个问题的正确位置。谢谢您的理解。@iBug大多数在这里发布编程问题的人这样做是因为他们在so上被禁止提问,这将导致迁移失败。因此,除非有特殊原因,我通常不会尝试迁移,例如,有人已经回答了这里,如果我们不迁移,答案将丢失。@DanHulme鉴于我编辑的内容质量和正确的格式,这一次可能值得一试。如果你愿意,我将不胜感激。谢谢。虽然将argv视为只读是一种很好的做法,但实际上我们可以知道它指向有效的读/写内存,因为C标准5.1.2.2.1保证了这一点。因此,我们可以很好地向argv写入数据,这样做是定义良好且可移植的。但我们当然不能写得越界。因此,如果argv[n]
是“hello”
,那么我们只能可靠地向该数组写入最多5+1=6个字符。这不是一个好主意,但是得到了C标准的支持。@Lundin-是的,你是对的。内存,指向argv[i]
当然是可写的。但很少有人能修改它。我只看到一种情况——在解析参数之前,如果程序使用不区分大小写的命令行语义,则大写或小写字符串。虽然将argv视为只读是一种良好的做法,但实际上我们可以知道它指向有效的读/写内存,因为C标准5.1.2.2.1保证了这一点。因此,我们可以很好地向argv写入数据,这样做是定义良好且可移植的。但我们当然不能写得越界。因此,如果argv[n]
是“hello”
,那么我们只能可靠地向该数组写入最多5+1=6个字符。这不是一个好主意,但是得到了C标准的支持。@Lundin-是的,你是对的。内存,指向argv[i]
当然是可写的。但很少有人能修改它。如果程序使用不区分大小写的命令行语义,在解析参数之前,我只查看一个大小写字符串。这主要是对i的注释