我的代码中使用strcpy

时间:2018-05-31 19:04:00

标签: 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_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);     
}

3 个答案:

答案 0 :(得分:3)

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

1)没有argv[1],即您尝试从NULL指针复制(即......如果程序以无参数启动,则可以访问argv[1]但是将返回NULL指针。因此,从它复制是非法的,可能会导致seg错误)。因此,如果您启动类似./program的程序,则程序将崩溃,因为argv[1]为NULL

2)argv[1]的长度超过目的地,即7个字符和终止NUL。如果是这样,你写出界限并可能导致段错误。

所以为了使代码正确,请执行:

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;
}

<强>顺便说一句

使用%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);

答案 1 :(得分:2)

这里有两个主要问题:您没有检查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);     
}

答案 2 :(得分:0)

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

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