Strcpy分段故障C.

时间:2014-08-27 15:34:42

标签: c strcpy

我正在学习一些新东西并陷入简单的strcpy操作。 我不明白为什么我第一次打印作品,但第二次它没有。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char *name;
    char *altname;

    name=(char *)malloc(60*sizeof(char));
    name="Hello World!";
    altname=name;
    printf("%s  \n", altname);
    altname=NULL;
    strcpy(altname,name);
    printf("%s  \n", altname);
    return 1;
}

4 个答案:

答案 0 :(得分:6)

问题从这里开始:

name=(char *)malloc(60*sizeof(char));
name="Hello World!";

您将malloc返回的值替换为字符串文字。

  1. 您泄漏了内存(因为您无法重新获得malloc返回的指针值)。拨打malloc的所有电话都与对free的相应电话相匹配。由于该指针值消失了,用该指针值调用free的机会也消失了。

  2. 您进一步写入NULL指针,这是未定义的行为(在您的情况下,会产生分段错误)。

答案 1 :(得分:4)

您需要为altname分配内存:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char *name;
    char *altname;

    name=(char *)malloc(60*sizeof(char));
    name="Hello World!";
    altname=name;
    printf("%s  \n", altname);
    altname=NULL;
    // allocate memory, so strcpy has space to write on ;)
    altname=(char *)malloc(60*sizeof(char));
    strcpy(altname,name);
    printf("%s  \n", altname);
    return 1;
}

答案 2 :(得分:2)

第一次,您altname指向与name相同的位置。这没关系,因为name指向有效的char*"Hello World!"字面的第一个元素)

// both point to beginning of "Hello World!" literal
altname=name;

第二次,您尝试将name指向的数据复制到altname所指向的位置,该位置在此阶段指向NULL。所以你试图写入NULL,这是错误的来源。

strncpy要求目标缓冲区是可写的,并且足够大以将源字符串的数据复制到其中。您需要使altname指向一个足够大的缓冲区,以便字符串name的内容指向。

altname = (char*)malloc(60*strlen(name)+1); // +1 for nul terminator
strcpy(altname, name);

另请注意,当您设置name = "Hello World!"时,会泄漏它最初指向的内存。你需要先释放它:

free(name);
name = "Hello World!";

答案 3 :(得分:1)

您正在尝试将值分配给无法存储空间的altname。首先将内存分配给altname然后分配

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char *name;
    char *altname;

    name=(char *)malloc(60*sizeof(char));
    name="Hello World!";
    altname=name;
    printf("%s  \n", altname);
    altname=NULL;
    altname=(char *)malloc(sizeof(name)); // allocate memory
    strcpy(altname,name);                 // Now assign 
    printf("%s  \n", altname);
    return 1;
}