Gdzie są stałe łańcuchowe przechowywane przez GCC i skąd te wskaźniki są mapowane?

Kiedy kompiluję i uruchamiam następujący program C na moim komputerze z systemem Linux x86_64, skompilowany przez GCC:

#include <stdio.h>

int main(void)
{
    char *p1 = "hello";               // Pointers to strings
    char *p2 = "hello";               // Pointers to strings
    if (p1 == p2) {                   // They are equal
    printf("equal %p %p\n", p1, p2);  // equal 0x40064c 0x40064c
                                      // This is always the output on my machine
    }
    else {
    printf("NotEqual %p %p\n", p1, p2);
    }
}

Zawsze otrzymuję wynik jako:

równy 0x40064c 0x40064c

Rozumiem, że łańcuchy są przechowywane w stałej tabeli, ale adres jest zbyt niski w porównaniu z pamięcią przydzielaną dynamicznie.

Porównaj z następującym programem:

#include <stdio.h>

int main(void)
{
    char p1[] = "hello";                // char arrar
    char p2[] = "hello";                // char array
    if (p1 == p2) {
    printf("equal %p %p\n", p1, p2);
    }
    else {                              // Never equal
    printf("NotEqual %p %p\n", p1, p2); // NotEqual 0x7fff4b25f720 0x7fff4b25f710
                                        // Different pointers every time
                                        // Pointer values too large
    }
}

Dwa wskaźniki nie są równe, ponieważ są to dwie tablice, które można niezależnie manipulować.

Chcę wiedzieć, w jaki sposób GCC generuje kod dla tych dwóch programów i jak są one mapowane do pamięci podczas wykonywania. Ponieważ dokumentacja ta byłaby już udokumentowana, tak często powtarza się wszelkie linki do dokumentacji.

questionAnswers(1)

yourAnswerToTheQuestion