简体   繁体   中英

C++ reference of a string literal

This code outputs a random memory address can anyone explain why and how?

#include<iostream>
using std::cout;

int main()
{
    cout<<&"hello";
    return 0;
}

output:

0x560d6984e048

...Program finished with exit code 0
Press ENTER to exit console.

A literal strings in C++ are really arrays of constant characters (including the null-terminator).

By using the pointer-to operator you get a pointer to that array.

It's somewhat equivalent to something like this:

#include <iostream>

char const hello_str[] = "hello";

int main()
{
    std::cout << &hello_str;
}

In C++, a string literal has the type const char[N] where N is the length of the string plus one for the null terminator. That array is an lvalue so when you do &"some string" , you are getting the address of the array that represents the string literal.

This does not work with other literals like integer literals because they are prvalues, and the address operator ( & ) requires an lvalue.

Like the other answers have already stated, in C and C++, a string is basically a pointer to an array of characters.

According to cppreference.com :

String literals have static storage duration, and thus exist in memory for the life of the program.

The C++ standard doesn't describe how exactly executables are supposed to look like, or where and how things get stored in memory. It, eg, describes storage duration and behaviors etc., but it is a platform independent standard . So this is implementation specific .

So why does this still work and what address do you see? It depends on your compiler and platform, but generally, your compiler will create an executable of your program[^1], eg, an ELF (Executable and Linkable Format) on Linux, or a PE (portable executable) on Windows.

In an ELF binary, literals are stored in the .rodata section (read-only data) and the machine instructions in the .text section. You can look at the binary the compiler spits out with certain compiler options, or online on Matt Godbolt's compiler explorer .

Let's look at the example you gave: https://gcc.godbolt.org/z/4s5Y66nY5

We see a label on top, .LC0 where your string is. It is part of the executable file. And this file has to be mapped into memory to be executed . Line 5 loads the address of that label into a register ( %esi ) before the call to the stream operation.

So what you see is the location of the string in the read-only section mapped to memory (more precisely, the address in the virtual address space of your process).

This as all rather Linux specific, because that is what I know best, but it is very similar on Windows and Mac.

Here is a nice (student??) paper that goes into more details about how GCC deals with string literals on Unix.

[1]: The compiler could generate other things, of course. An object file. Maybe you want to create a static library, or a dynamic library. But let's keep it simple and talk about executables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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