2

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.
Benjamin Maurer
  • 3,602
  • 5
  • 28
  • 49
John Mellow
  • 116
  • 5
  • 3
    what output did you expect? – 463035818_is_not_an_ai Oct 04 '21 at 14:49
  • `&` here has nothing to do with a reference. It is the adress-of-operator – 463035818_is_not_an_ai Oct 04 '21 at 14:49
  • Might be relevant: [memory - C++ string literal data type storage - Stack Overflow](https://stackoverflow.com/questions/2327841/c-string-literal-data-type-storage) and [c - Why are the memory addresses of string literals so different from others', on Linux? - Stack Overflow](https://stackoverflow.com/questions/40677631/why-are-the-memory-addresses-of-string-literals-so-different-from-others-on-li) (also ASLR might be related) – user202729 Oct 04 '21 at 14:52
  • i expected an error XD – John Mellow Oct 04 '21 at 14:52
  • 2
    @JohnMellow Usually you would want to point that out in the question and explain some reason (compared to taking the address of an integer constant, etc.) (because otherwise there would be too much "beginner" things to explain) – user202729 Oct 04 '21 at 15:03
  • Also note that just because a program compiles and runs correctly doesn't mean that it's standard compliant (see undefined behavior for example) – user202729 Oct 04 '21 at 15:04
  • You not only expected an error, you assumed this to still be the correct behavior despite it not happening. It shows because you assumed we'd think the same thing. Whenever the expected doesn't happen, challenge your expectations, don't hold on to them. It will make you a better developer. – StoryTeller - Unslander Monica Oct 04 '21 at 15:55

3 Answers3

2

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;
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • so "hello" is stored somewhere in memory ? – John Mellow Oct 04 '21 at 14:52
  • @JohnMellow Yes, otherwise it would not be able to get its individual characters. – Some programmer dude Oct 04 '21 at 14:54
  • is there any book that can help me get all this minute details of c++ ? rather than the official docs ? – John Mellow Oct 04 '21 at 14:55
  • 1
    @JohnMellow of course, it _has to be_ if you want to use it in your program. Now, because it is a compile time constant, e.g., in Unix ELF executables, they are stored in the .rodata (read-only data) section - but they still must be mapped to memory, just like the actual program instructions. Otherwise the computer can't use it, right? – Benjamin Maurer Oct 04 '21 at 14:55
  • 1
    @JohnMellow this is not a C++ detail and not part of the C++ standard. This is operating system dependent. You can read up on the Unix ELF format if you want, or the Windows PE format. If you want to go _really deep_, you need to learn about operating systems and compilers. – Benjamin Maurer Oct 04 '21 at 14:57
  • @BenjaminMaurer woaaah thanks alot will look into it defn. – John Mellow Oct 04 '21 at 15:01
  • 1
    @JohnMellow Exactly where the string is stored (in the executable file or in memory) is OS-dependent , but the C++ specification guarantees that it's available to the program as a null-terminated array of constant characters. – Some programmer dude Oct 04 '21 at 15:14
2

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.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • but where is that array ? or every string will be implicitly represented as an array ? – John Mellow Oct 04 '21 at 14:54
  • 1
    @JohnMellow Every string literal is represented as an array, but we don't know where they are stored. That's left up to the implementation to decide. It could be it doesn't even exist once the compiler is done optimizing the code. For instance, duplicate string literals are allowed to all reference the same array, instead of having a unique array per literal. – NathanOliver Oct 04 '21 at 14:56
0

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, e.g., 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], e.g., 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.

Benjamin Maurer
  • 3,602
  • 5
  • 28
  • 49