Дэвид, спасибо за ваше время и предложение. Пример программы не работал, потому что я не включил stdlib.h
в мой C-файл, и поэтому указатель, возвращаемый malloc, был 32-битным. Проблема, с которой я столкнулся, была с производственным кодом, который немного отличался от примера кода.
tristopia, ваше объяснение абсолютно верно. Я столкнулся с той же проблемой.
В моих производственных файлах C я столкнулся с проблемой, как показано ниже
a.c
call_test1()
{
char* temp;
temp = (char *)test1();
}
b.c
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
Когда str
был возвращен test1()
, указатель содержал 64-битный адрес (я проанализировал регистр rx (в котором хранится возвращаемое значение функции) в windbg, используя "r rx"), но когда он был назначен temp
, оно было усечено до 32-битного адреса).
Проблема возникла из-за
- Не включая подпись
test1()
в файле a.c
- Тип, возвращая возвращаемое значение в символ *
Модифицированный источник
a.c
char * test1();
call_test1()
{
char* temp;
temp = test1();
}
b.c
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
Я получил решение методом проб и ошибок, но Тристопия объяснила причину.
64-битные ноты
- Используйте% p вместо% lx, чтобы напечатать адрес указателя в 64-битной среде.
- Включите сигнатуру функции и попытайтесь избежать указателей типов
- В Windows,
Если вы перекомпилируете свой код C / C ++ в 64-битный EXE или DLL, вы должны протестировать его с установленным значением реестра AllocationPreference.
Чтобы принудительно распределять выделения с более высоких адресов перед более низкими адресами в целях тестирования, укажите MEM_TOP_DOWN
при вызове VirtualAlloc
или установите следующее значение реестра на 0x100000
:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference