复制内存时为什么分段出错

use*_*878 2 c segmentation-fault

我在x86_32上运行ubuntu ...并且在运行此程序时我一直遇到分段错误.

enter code here
#include<stdio.h>
#include<stddef.h>
char *memcp(char *dest, const char *src, size_t n)
{

    char *dp = dest;
    const char *sp = src;
    while(n--)
        *dp++ = *sp++;
    return dest;

}

int main()
{

    char *s = "abcde";
    char *d;
    char *r = memcp(d,s,6);
    printf("%s",r);

    return(0);
}
Run Code Online (Sandbox Code Playgroud)

这段代码的问题在于它在我朋友的x86_64机器上运行在windows和ubuntu上.请帮帮我..

dre*_*lax 7

至少有两种方法可以做到这一点:

malloc 方法:

int main(void)
{
    char *s = "abcde";
    char *d = malloc(6);
    char *r = memcp(d, s, 6);
    printf("%s",r);

    free(d);
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

数组方法:

int main(void)
{
    char *s = "abcde";
    char d[6];
    memcp(d, s, 6);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,将缓冲区长度硬编码到代码中通常不是一个好主意(例如,您正在硬编码6).如果输入的大小发生变化而您忘记更新数字6,则会出现问题.

你得到分段错误的原因是因为指针d没有指向任何地方.在您的memcp函数中,您正在尝试编写此指针,但因为它没有指向程序崩溃的任何有意义的地方.在C标准中,这称为未定义行为,基本上它意味着任何事情都可能发生.

此外,您可能感兴趣的是,标准C库中已有两个功能可用,memmove并且memcpy.memmove如果源和目标区域重叠,则非常有用.如果你知道它们不会重叠,memcpy可能会更快.

最后,我想指出,您不应该接受Artur关于未初始化指针使用的建议.你永远不应该依赖未初始化指针的值,这样做意味着你的程序的行为没有明确定义.C语言规范的附录J提到了以下未定义的行为:

J.2未定义的行为

  1. 在以下情况下,行为未定义:
    • ...
    • 具有自动存储持续时间的对象的值在不确定时使用.
    • ...

  • @Artur Mustafin:*"它不指向任何地方"*在此上下文中应该被理解为*"它没有被定义为指向任何地方"*. (2认同)
  • @Artur:您正在考虑实施级别.C语言规范没有提到数据段和CPU级异常,它定义了行为.而且,你误解了我说的话; 在实现级别`d`指向无处可靠的实用或有用.就C语言规范而言,它只是未定义的行为. (2认同)