c - 内存中的 strcpy 和字符串表示

标签 c printf undefined-behavior buffer-overflow strcpy

我有一个这样的程序(x86_64 GNU/Linux)

int main()
{
    char s[] = "123456789";
    char d[] = "123";
    strcpy(d, s);

    printf("%p, %0p\n", s, d);
    printf("%s, %s", s, d);

    return 0;
}

输出是:0xeb6d2930 0xeb6d2910 123456789 123456789 我对结果有点困惑 我想内存中的程序是这样的:

  • '9','\0' 。 .
  • '5','6','7','8'
  • 0x7fff813af310: '1','2','3','4'
  • 0x7fff813af300: '1','2','3','\0'

所以结果应该是 *s = "789", *d = "123456789"

你们能解释一下为什么结果和我想的不一样吗? 我将格式说明符更改为 %p 以打印 d 和 s 的地址 我知道 s 和 d 是重叠的,所以 d 没有足够的空间 持有 s 这可能会导致未定义的行为,但无论如何我想知道 为什么结果是 *s = "123456789"*d = "123456789"

最佳答案

你的程序在这两个方面有未定义的行为:

  • strcpy() 缓冲区溢出:不要写入不属于您的内存。
  • printf() 的格式说明符错误:使用 %p 打印指针地址。不过仅适用于数据指针。

请为 main 使用正确的原型(prototype),您几乎已经拥有它(这可能是 UB,尽管我没有遵循所有论点):

int main(void)
int main(int argc, char* argv[])

或兼容或实现定义的扩展有效。

未定义的行为意味着一切正常,甚至是鼻涕虫。

关于c - 内存中的 strcpy 和字符串表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23061492/

相关文章:

c - 如何复制给定字符串中所有不重复的单词?

c - for (unsigned char i = 0; i<=0xff; i++) 产生无限循环

c - printf() 中大 float 的奇怪行为并分配给一个 int

c++ - 带有 %s 和 std::string 的 sprintf 给出乱码

c++ - 标准中关于超出范围指针的未定义行为的歧义

c - 使用/clr 支持编译的 C++-CLI 库调试 C 程序

c - 从文本文件中读取单词(一行中的单个单词)

c - 使用带有千位分组格式(撇号)的 ICC 和 printf 的警告

c++ - 有两个具有不同值的指针引用同一个对象是未定义的行为吗?

c++ - 为什么赋值表达式中的重叠必须是精确的并且对象必须具有相同的类型,这是什么意思?