简体   繁体   English

内存中的strcpy和字符串表示

[英]strcpy and string presentation in memory

I have a program like this(x86_64 GNU/Linux) 我有一个像这样的程序(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;
}

and the output is : 0xeb6d2930 0xeb6d2910 123456789 123456789 I am little confused with the result I think the program in the memory is like this: 输出为:0xeb6d2930 0xeb6d2910 123456789 123456789我对结果有点困惑,我认为内存中的程序是这样的:

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

so the result should be *s = "789", *d = "123456789" 因此结果应为* s =“ 789”,* d =“ 123456789”

could you guys explain why the result isn't as I thought? 你们能解释为什么结果不如我想的吗? I changed the format specifier to %p to print the address of d and s I know that s and d are overlapped so there is not enough space for d to hold s which may lead to undefined behaviour,but anyway I was wondering why the result is *s = "123456789" *d = "123456789" 我将格式说明符更改为%p以打印d和s的地址,我知道s和d重叠,因此没有足够的空间容纳d来容纳s,这可能会导致不确定的行为,但是无论如何我都想知道为什么结果是* s =“ 123456789” * d =“ 123456789”

Your program has undefined behavior on these two counts: 您的程序在以下两个方面具有未定义的行为:

  • Buffer overflow with strcpy() : Do not write to memory you do not own. 使用strcpy()导致缓冲区溢出:不要写入您不拥有的内存。
  • Wrong format specifier for printf() : Use %p to print pointer addresses. printf()格式说明符错误:使用%p打印指针地址。 Only works for data-pointers though. 但是仅适用于数据指针。

Please use the proper prototype for main , you nearly have it (this might be UB, though I did not follow all the argument): 请为main使用合适的原型,您几乎可以使用它(这可能是UB,尽管我并未遵循所有论点):

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

or compatible or implementation defined extensions are valid. 或兼容或实现定义的扩展名有效。

Undefined Behavior means everything goes, even nasal demons. 未定义的行为意味着一切,甚至是鼻恶魔。

Your program invokes undefined behavior because: 您的程序调用未定义的行为,因为:
1. d doesn't have enough space to hold the string larger than 4 bytes (including \\0 ). 1. d没有足够的空间来容纳大于4个字节的字符串(包括\\0 )。
2. You are using wrong format specifier to print the address. 2.您使用了错误的格式说明符来打印地址。

Result is either expected or unexpected. 结果是预期的还是意外的。

From the output you show the address layout and it's initial content seem to be: 从输出中可以看到地址布局,它的初始内容似乎是:

       offset 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  
d: 0xeb6d2910 30 31 32 00 xx xx xx xx xx xx xx xx xx xx xx xx | 1 2 3 . . . . . . . . . . . . .
   0xeb6d2920 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx | . . . . . . . . . . . . . . . .
s: 0xeb6d2930 30 31 32 33 34 35 36 37 38 39 00 xx xx xx xx xx | 1 2 3 4 5 6 7 8 9 . . . . . . . 

After the strcpy(d, s) : strcpy(d, s)

       offset 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  
d: 0xeb6d2910 30 31 32 33 34 35 36 37 38 39 00 xx xx xx xx xx | 1 2 3 4 5 6 7 8 9 . . . . . . . 
   0xeb6d2920 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx | . . . . . . . . . . . . . . . .
s: 0xeb6d2930 30 31 32 33 34 35 36 37 38 39 00 xx xx xx xx xx | 1 2 3 4 5 6 7 8 9 . . . . . . . 

However, as for d fewer memory had been allocated as used during strcpy() the code invokes undefeind behaviour. 然而,对于d期间使用更少的存储器已分配strcpy()的代码调用undefeind行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM