我的 strcpy 中的分段错误

Segmentation fault in my strcpy

我正在编写自己的 strcpy,因为 string.h 中的默认值仅接受 const char * 作为要复制的源字符串。 我正在尝试这个非常基本的原型(是的,return 没有意义,我只是在尝试):

int copyStrings(char * dest, char * source){
    int i=0;
    while(source[i]!='[=10=]'){
        dest[i]=source[i];
        i++;
    }
    dest[i]='[=10=]';
    return 0;
}

它在 gdb 中给我 SIGSEGV, Segmentation Fault 错误,在第 dest[i]=source[i] 行,就在 第一个 字符处。我很确定 dest[i] 不是字符串文字,所以我应该能够修改它。

我做错了什么?

编辑:这是调用

int main(){
    char * str = (char*)malloc((int)sizeof(double));
    char * str2 = (char *)malloc((int)sizeof(int));
    str = "hello";
    str2 = "hey jude";
    copyStrings(str2, str);
    free(str);
    free(str2);
    return 0;
}

这是将字符串文字分配给 str2 - 这正是您声称自己没有做的事情。这实际上是您的段错误的原因。

str2 = "hey jude";

它也导致内存泄漏,因为在此之前,您 malloc 已经分配了一些内存并将其分配给 str2。但是没有足够的内存来保存字符串。通常 int 是 4 个字节,您需要 9 个字节来存储该字符串。

你想要做的是这个,它分配与字符串中一样多的字节,再加上一个额外的字节来存储末尾的 [=17=] 终止字符。

str2 = malloc(strlen("hey jude")+1);
strcpy(str2,"hey jude");

或者在某些系统上,您可以使用 POSIX 函数 strdup(),它可以在一个方便的函数调用中有效地完成上述工作。

str2 = strdup("hey jude");

让我们一行一行看,看看哪里出错了:

int main(){
    char * str = (char*)malloc((int)sizeof(double));
    char * str2 = (char *)malloc((int)sizeof(int));
    str = "hello";
    str2 = "hey jude";
    copyStrings(str2, str);
    free(str);
    free(str2);
    return 0;
}

int main(){ - 这是 main 的错误定义。应该是 int main(int argc, char **argv)

char * str = (char*)malloc((int)sizeof(double)); - 定义 str,然后分配(可能)8 个字节的内存并将其地址分配给 strmalloc 采用 size_t 参数,因此转换 (int)sizeof(double) 是不正确的。此外,在 C 中,malloc 的 return 值应该 never 被转换。所以这一行应该是 char * str = malloc(sizeof(double));

char * str2 = (char *)malloc((int)sizeof(int)); - 所有与前一行相同的问题。应该是 char *str2 = malloc(sizeof(int));

str = "hello"; - 导致内存泄漏,因为您刚刚分配的两行内存现在已经无法挽回地丢失了。你在这里有两个选择——要么在定义 str 时不分配内存,要么先释放它。让我们做后者:

free(str);
str = "hello";

str2 = "hey jude"; - 同样的问题,类似的解决方案:

free(str2);
str2 = "hey jude";

copyStrings(str2, str); - 此处您告诉例程将常量字符串 "hello" 复制到常量字符串 "hey jude" 的顶部。这将在某些系统 上正常工作,但会在其他系统 上崩溃。问题在于常量字符串 "hey jude" 的处理。如果它存储在可修改的内存中,代码就可以正常工作。但是,如果它存储在标记为不可修改的内存中,它就会爆炸。在你的系统上似乎是后者。要解决此问题,您可能需要返回上一行并将其更改为

str2 = malloc(20);

这比您需要的内存多,但它会工作得很好。

free(str); - 您正试图释放常量字符串 "hello",它不是动态分配的内存。这需要在分配 str = "hello";.

之前完成

free(str2; - 与上述相同的问题。这需要在分配 str2 = "hey jude";.

之前完成

} - 正确

祝你好运。