使用strcpy在我的代码中出现分段错误

使用strcpy在我的代码中出现分段错误,c,segmentation-fault,strcpy,C,Segmentation Fault,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

我在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_two\n\n", 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);     
}
#包括
#包括
int main(int argc,char*argv[])
{
int值=5;
字符缓冲区_-one[8],缓冲区_-two[8];
strcpy(buffer_one,one);//将“one”放入buffer_one
strcpy(buffer_-two,two);//将“two”放入buffer_-two中
printf(“[BEFORE]buffer\u-two位于%p,包含\'%s\'\n',buffer\u-two,buffer\u-two);
printf(“[BEFORE]buffer\u one位于%p,包含\'%s\'\n',buffer\u one,buffer\u one);
printf(“\n[STRCPY]将%d字节复制到缓冲区\u-two\n\n”,strlen(argv[1]);//将第一个参数复制到缓冲区\u-two

strcpy(buffer_-two,argv[1]);//在使用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;
}

hai是传递的参数。这里argc是2,argv[1]=hai

在使用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;
}

hai是传递的参数。此处argc为2,argv[1]=hai

seg故障可能有两个原因

1) 没有
argv[1]
,即尝试从空指针复制(即…如果程序启动时没有参数,
argv[1]
可以访问,但会返回空指针。因此,从它复制是非法的,可能会导致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 program\n");
    }
    return 0;
}
应该是

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

seg故障可能有两个原因

1) 没有
argv[1]
,即尝试从空指针复制(即…如果程序启动时没有参数,
argv[1]
可以访问,但会返回空指针。因此,从它复制是非法的,可能会导致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 program\n");
    }
    return 0;
}
应该是

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 program\n");
      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_two\n\n", strlen(argv[1])); //Copy first argument into buffer_two

    strncpy(buffer_two, argv[1], 8); // <---- here
    if(buffer_two[7] != '\0'){
       printf("[ERROR] string did not fit into buffer, truncating\n");
       buffer_two[7] = '\0';
    }

    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);     
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
如果(argc<2){
printf(“请在调用此程序时输入参数\n”);
返回退出失败;
}
int值=5;
字符缓冲区_-one[8],缓冲区_-two[8];
strcpy(buffer_one,one);//将“one”放入buffer_one
strcpy(buffer_-two,two);//将“two”放入buffer_-two中
printf(“[BEFORE]buffer\u two位于%p,包含\'%s\'\n',(void*)buffer\u two,buffer\u two);
printf(“[BEFORE]buffer\u one位于%p并包含\'%s\'\n',(void*)buffer\u one,buffer\u one);
printf(“\n[STRCPY]将%zu字节复制到缓冲区\u-two\n\n”,strlen(argv[1]);//将第一个参数复制到缓冲区\u-two

strncpy(buffer_-two,argv[1],8);//这里有两个主要问题:您没有检查
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 program\n");
      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_two\n\n", strlen(argv[1])); //Copy first argument into buffer_two

    strncpy(buffer_two, argv[1], 8); // <---- here
    if(buffer_two[7] != '\0'){
       printf("[ERROR] string did not fit into buffer, truncating\n");
       buffer_two[7] = '\0';
    }

    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);     
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
如果(argc<2){
printf(“请在调用此程序时输入参数\n”);
返回退出失败;
}
int值=5;
字符缓冲区_-one[8],缓冲区_-two[8];
strcpy(buffer_one,one);//将“one”放入buffer_one
strcpy(buffer_-two,two);//将“two”放入buffer_-two中
printf(“[BEFORE]buffer\u two位于%p,包含\'%s\'\n',(void*)buffer\u two,buffer\u two);
printf(“[BEFORE]buffer\u one位于%p并包含\'%s\'\n',(void*)buffer\u one,buffer\u one);
printf(“\n[STRCPY]将%zu字节复制到缓冲区\u-two\n\n”,strlen(argv[1]);//将第一个参数复制到缓冲区\u-two

strncpy(buffer_-two,argv[1],8);//您将什么作为第一个参数传递给程序(即,
argv[1]
)?strlen(argv[1])
行打印什么?您应该先检查
argc
,然后再假设
argv[index]中有内容
。使用
strncpy
将副本限制在缓冲区的长度也没有什么坏处,因为程序无法控制argv[1]
的长度,可能会导致缓冲区溢出。除此之外:
buffer\u one,buffer\u one
=>
(void*)当提供
%p
说明符时,buffer\u one,buffer\u one
。失败的原因很大程度上取决于您如何调用此程序。您发出的运行它的确切命令是什么?您将什么作为第一个参数传递给程序(即
argv[1]
)?strlen(argv[1]是什么)
line print?在假定某个内容位于
argv[index]
中之前,您应该检查
argc
。使用
strncpy
将副本限制在缓冲区的长度也不会有什么影响,因为程序无法控制
argv[1]的长度
是并可能导致缓冲区溢出。旁白:
缓冲区一,缓冲区一
==>
(void*)缓冲区一,缓冲区一
在提供
%p
说明符时