C - 使用 strcpy 的代码中的分段错误



我在strcpy(buffer_two,argv[1](之后遇到分段错误; 不确定这里出了什么问题,我希望能帮助了解出了什么问题以及为什么我会出现细分错误。

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int value = 5;
char buffer_one[8], buffer_two[8];
strcpy(buffer_one, "one"); // Put "one" into buffer_one
strcpy(buffer_two, "two"); // Put "two" into buffer_two
printf("[BEFORE] buffer_two is at %p and contains '%s'n", buffer_two, buffer_two);
printf("[BEFORE] buffer_one is at %p and contains '%s'n", buffer_one, buffer_one);
printf("n[STRCPY] copying %d bytes into buffer_twonn", strlen(argv[1])); //Copy first argument into buffer_two
strcpy(buffer_two, argv[1]); // <---- here
printf("[After] buffer_two is at %p and contains '%s'n", buffer_two, buffer_two);
printf("[After] buffer_one is at %p and contains '%s'n", buffer_one, buffer_one);
printf("[AFTER] value is at %p and is %d (0x%08x)n", &value, value, value);     
}

SEG 故障有两个可能的原因。

1(没有argv[1],即您尝试从空指针复制(即...如果程序在没有参数的情况下启动,则可以访问argv[1],但将返回 NULL 指针。因此,从中复制是非法的,并可能导致 seg 错误(。因此,如果您像./program一样启动程序,程序将崩溃,因为argv[1]为空

2(argv[1]的长度超过目的地,即 7 个字符和一个终止 NUL。如果是这样,则写入越界并可能导致 seg 错误。

因此,要正确获取代码,请执行以下操作:

int main(int argv,char * argv[])
{
char buffer_two[8];
if ((argc >  1) && (strlen(argv[1]) < 8)) // Make sure arg[1] is there
// Make sure it's not too long
{
strcpy(buffer_two, argv[1]);
}
else
{
printf("Illegal start of programn");
}
return 0;
}

顺便说一句,福尔

使用%p打印指针时,请确保投射到void*

所以这个

printf("[After] buffer_two is at %p and contains '%s'n", buffer_two, buffer_two);

应该是

printf("[After] buffer_two is at %p and contains '%s'n", (void*)buffer_two, buffer_two);

这里有两个主要问题:您不检查argc以查看argv[1]是否存在,并且您盲目地将argv[1]复制到可能不够大的缓冲区中,无法容纳它。 我还修复了一些与您的 printf 语句相关的编译器警告。 下面是一个使用您的代码如何处理此类事情的示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
if(argc < 2) {
printf("Please enter an argument when invoking this programn");
return EXIT_FAILURE;
}
int value = 5;
char buffer_one[8], buffer_two[8];
strcpy(buffer_one, "one"); // Put "one" into buffer_one
strcpy(buffer_two, "two"); // Put "two" into buffer_two
printf("[BEFORE] buffer_two is at %p and contains '%s'n", (void *)buffer_two, buffer_two);
printf("[BEFORE] buffer_one is at %p and contains '%s'n", (void *)buffer_one, buffer_one);
printf("n[STRCPY] copying %zu bytes into buffer_twonn", strlen(argv[1])); //Copy first argument into buffer_two
strncpy(buffer_two, argv[1], 8); // <---- here
if(buffer_two[7] != ''){
printf("[ERROR] string did not fit into buffer, truncatingn");
buffer_two[7] = '';
}
printf("[After] buffer_two is at %p and contains '%s'n", (void *)buffer_two, buffer_two);
printf("[After] buffer_one is at %p and contains '%s'n", (void *)buffer_one, buffer_one);
printf("[AFTER] value is at %p and is %d (0x%08x)n", (void *)&value, value, value);     
}

在使用 argv 之前检查 argc 值。仅当 argc>1 时才使用 strcpy 。在 strcpy(( 之前做一个条件语句

例如...

int main(int argv,char * argv[])
{
char buffer[10];
if (argc >  1 && strlen(argv[1]) < 10)
{
strcpy(&buffer[0],argv[1]);
}
return 0;
}

您应该通过以下方式运行程序

./a.out hai

海是通过的论点。这里 argc 是 2 ,argv[1] = hai

相关内容

  • 没有找到相关文章

最新更新