Dlaczego ten kod segfault na architekturze 64-bitowej, ale działa dobrze na 32-bitowej?
Natknąłem się na następującą zagadkę C:
P: Dlaczego następujący program segfault na IA-64, ale działa dobrze na IA-32?
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Wiem, że rozmiar int
Na 64-bitowej maszynie może nie być taki sam jak rozmiar wskaźnika (int
może wynosić 32 bity, a wskaźnik 64 bity). Nie jestem jednak pewien jak to się odnosi do powyższego programu.
Jakieś pomysły?
3 answers
Rzut do int*
maskuje fakt, że bez właściwego #include
przyjmuje się, że typ powrotu malloc
to int
. IA-64 mA sizeof(int) < sizeof(int*)
, co czyni ten problem oczywistym.
(zauważ również, że z powodu niezdefiniowanego zachowania może nadal nie działać nawet na platformie, na której sizeof(int)==sizeof(int*)
Jest Prawdziwa, na przykład, jeśli konwencja wywołująca używała innych rejestrów do zwracania wskaźników niż liczby całkowite)
The comp.lang.C FAQ ma wpis dyskutujący dlaczego casting na return from {[2] } nigdy nie jest potrzebny i potencjalnie zły .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:57
Najprawdopodobniej dlatego, że nie zawiera pliku nagłówkowego dla malloc
i chociaż kompilator normalnie ostrzegałby Cię o tym, fakt, że wyraźnie rzucasz zwracaną wartość oznacza, że mówisz mu, że wiesz, co robisz.
Oznacza to, że kompilator oczekuje, że int
zostanie zwrócone z malloc
, które następnie rzuca do wskaźnika. Jeśli są różnej wielkości, to będzie Ci smutno.
Dlatego ty nigdy nie rzucaj malloc
powrotu w C. void*
to, że zwróci, zostanie domyślnie przekonwertowane na wskaźnik właściwego typu(chyba że nie uwzględniłeś nagłówka, w którym to przypadku prawdopodobnie ostrzegłby Cię o potencjalnie niebezpiecznej konwersji int-to-pointer).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-23 07:43:29
Dlatego nigdy nie kompilujesz bez ostrzeżeń o brakujących prototypach.
Dlatego nigdy nie rzucasz powrotu malloca w C.
Cast jest potrzebny do kompatybilności z C++. Nie ma powodu (Czytaj: nie ma powodu tutaj), aby to pominąć.
Kompatybilność z C++ nie zawsze jest potrzebna, a w kilku przypadkach nie jest w ogóle możliwa, ale w większości przypadków jest bardzo łatwa do osiągnięcia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-25 17:11:19