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.