Nie możesz robić, co chcesz w przenośny sposób, ponieważ standard języka C nie określa stos, część programu, a sterty jako odrębne obszary. Ich lokalizacja może zależeć od architektury procesora, systemu operacyjnego, modułu ładującego, łącznika i kompilatora. Próbowanie odgadnąć, gdzie wskazuje wskaźnik, przerywa abstrakcję dostarczoną przez C, więc prawdopodobnie nie powinieneś tego robić.
Istnieją jednak sposoby na napisanie kodu, który będzie słusznym odgadywaniem dla określonego środowiska. Robisz to, badając adresy istniejących obiektów i szukając wzorów. Rozważ następujący program.
#include <stdlib.h>
#include <stdio.h>
void
function()
{
int stack2;
printf("stack2: %15p\n", &stack2);
}
int
main(int argc, char *argv[])
{
int stack;
void *heap = malloc(1);
void *heap2 = malloc(1);
printf("program: %15p\n", main);
printf("heap: %15p\n", heap);
printf("heap2: %15p\n", heap2);
printf("stack: %15p\n", &stack);
function();
return 0;
}
Badając jego wydruki, możesz zobaczyć wzorzec, taki jak na przykładzie systemu x64 Linux.
program: 0x400504
heap: 0x1675010
heap2: 0x1675030
stack: 0x7fff282c783c
stack2: 0x7fff6ae37afc
Z powyższego można stwierdzić, że (prawdopodobnie) sterta rośnie w górę z 0x1675010, cokolwiek pod nim jest kod programu (lub dane statyczne, które nie wspominając), i że stos rośnie w sposób sposób nieprzewidywalny (prawdopodobnie z powodu losowania stosu) wokół bardzo dużego adresu, takiego jak 0x7fff282c783c.
Porównaj to z mocy cieplnej przy 32-bitowym Intel Linux:
program: 0x804842f
heap: 0x804b008
heap2: 0x804b018
stack: 0xbf84ad38
stack2: 0xbf84ad14
Microsoft Windows i 32-bitowego Microsoft kompilator C:
program: 01271020
heap: 002E3B00
heap2: 002E3B10
stack: 0024F978
stack2: 0024F964
gcc pod Windows Cygwin:
program: 0040130B
heap: 00A41728
heap2: 00A417A8
stack: 0028FF44
stack2: 0028FF14
gcc pod Intel 32-bitowy FreeBSD:
program: 0x8048524
heap: 0x804b030
heap2: 0x804b040
stack: 0xbfbffb3c
stack2: 0xbfbffb1c
gcc pod Intel 64-bitowym FreeBSD:
program: 0x400770
heap: 0x801006058
heap2: 0x801006060
stack: 0x7fffffffdaec
stack2: 0x7fffffffdabc
gcc pod SPARC-64 FreeBSD:
program: 0x100860
heap: 0x40c04098
heap2: 0x40c040a0
stack: 0x7fdffffe9ac
stack2: 0x7fdffffe8dc
PowerPC z systemem MacOS X:
program: 0x1ed4
heap: 0x100120
heap2: 0x100130
stack: 0xbffffba0
stack2: 0xbffffb38
PowerPC z systemem Linux:
program: 0x10000514
heap: 0x100c6008
heap2: 0x100c6018
stack: 0xbff45db0
stack2: 0xbff45d88
StrongARM działa NetBSD:
program: 0x1c5c
heap: 0x5030
heap2: 0x5040
stack: 0xefbfdcd0
stack2: 0xefbfdcb4
i ARMv6 systemem Linux:
program: 0x842c
heap: 0xb63008
heap2: 0xb63018
stack: 0xbe83eac4
stack2: 0xbe83eaac
Jak widać możliwości są nieograniczone.
Zobacz odpowiedzi na [to pytanie] (http://stackoverflow.com/questions/276612/checking-if-something-was-malloced). –
W systemie Windows możesz użyć rozszerzenia '! Address' programu WinDbg, aby to ustalić. Nie wiem o * systemach operacyjnych opartych na nix. – user1354557