只要进程处于活动状态,指向字符串文字的 const char* 是否就持久存在?

问题描述 投票:0回答:2

我有如下功能:

const char* get_message() {
    return "This is a constant message, will NOT change forever!";
};

const char* get_message2() {
    return "message2";
};

我计划在我的应用程序的任何地方使用它们,即使在不同的线程中。

我想知道这些字符串的生命周期,即在函数之外使用这些

const char*
字符串是否安全
get_message

我猜想硬编码的

const char*
字符串将被编译到应用程序的代码段而不是数据段中,所以也许像上面那样使用它们是安全的?

c++ constants constexpr lifetime null-terminated
2个回答
4
投票

是的,这样做是安全的。你的假设是正确的。


0
投票

让我们看看代码中 gdb

发生了什么

我们在函数中放置断点,返回指向常量字符串的指针:

代码通过以下指令获取该字符串:

0x000055555555514a <+8>:    lea    0xeb3(%rip),%rax        # 0x555555556004

这条指令的作用是计算“message2”的地址。 我们在这里看到 PIC(位置无关代码)的含义。 “message2”字符串的地址不是硬编码为绝对地址,而是计算为相对地址,作为下一条指令地址 (0x555555555151 + 0xeb3) 的硬编码偏移 0xeb3 并放入寄存器 rax

(gdb) i r $rax
rax            0x555555556004      93824992239620

现在我们在 rax 中有“message2”的地址:

(gdb) x/s 0x555555556004
0x555555556004: "message2"

这意味着进程将始终获得“message2”的正确地址,无论它加载到内存中的哪个位置。

现在让我们看看地址0x555555556004在进程地址映射中的位置 是:

0x555555556000     0x555555557000     0x1000     0x2000  r--p   /home/drazen/proba/main

因此该部分不可执行且不可写,只是可读(r--p)。

当我们使用 readelf 检查时,它显示它位于 ELF 文件的 .rodata 部分:

drazen@HP-ProBook-640G1:~/proba$ readelf  -x .rodata main

Hex dump of section '.rodata':
0x00002000 01000200 6d657373 61676532 00       ....message2.

所以答案是,这个字符串不会被硬编码在 ELF 文件的代码段 .text 中,而是被硬编码在 rodata 中,但是,是的,当内存中存在长进程时,它就会存在。

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.