【问题标题】:Printing two string literals with same value gives same address打印两个具有相同值的字符串会给出相同的地址
【发布时间】:2016-09-19 21:41:44
【问题描述】:

谁能解释一下:

#include <stdio.h>

void some_fn(char *x)
{
    printf("%d\n", x);
}

int main()
{
    // They are stored on the same memory address
    some_fn("A");
    some_fn("A");

    some_fn("B");
}

为什么会:

    some_fn("A");
    some_fn("A");

打印存储在同一个内存地址吗?

【问题讨论】:

  • 因为"A"是一个字符串文字,它很可能进入程序的只读部分,并且编译器足够聪明,可以实现"A""A"是同一个字符串,因此它只存储一次并在任何时候使用该地址。此外,使用printf("%p"...) 打印出指针
  • 更好的问题是为什么不应该将它们存储在同一个地址中?
  • 而且您没有将任何chars 传递给您的函数。您正在传递指向char 的指针,正如它所需要的那样。这些指针是字符串字面量(char 的数组)衰减为指针的结果,就像任何数组值作为函数参数出现时一样。
  • 如果您执行了char str[] = "A";,这将强制编译器创建字符串文字初始值设定项的可修改副本。 (它仍然可以优化它,因为它可以内联 some_fn 并看到你没有做任何需要单独副本的事情)。 const char str[] = "A"; 可能不会导致任何浪费的复制。
  • @Barmar 我确实认为,我最初认为:由于字符串文字不能更改,那么编译器会认为它们是相同的东西并使用现有的而不是分配更多的记忆,但后来我想我最好不要猜测并问别人。

标签: c memory memory-management cpu-architecture


【解决方案1】:

首先,关闭使用%d 打印指针(就像您在编辑之前在代码中所做的那样)是无效的,并导致未定义的行为。您应该改用%p 指针。

话虽如此,对some_fn 的两个调用都被传递了一个字符串文字,每个都恰好是相同的。字符串文字通常存储在内存的只读部分中,当特定字符串文字多次出现在代码中时,编译器通常会使用该文字的单个实例。所以在这种情况下,当它出现在不同的地方时,该文字的地址是相同的。

【讨论】:

  • 感谢您的更正,我确实编辑了我的原始帖子。这也是我最初的想法,编译器不会浪费内存注意到两个相同的字符串文字。
  • @dud3 请不要使用答案中提供的更正来编辑问题。这让整个帖子看起来很混乱。
  • @2501 Roger 那,对不起。
猜你喜欢
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
  • 2012-08-08
  • 2021-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多