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?

Author: user7, 2011-09-25

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 .

 119
Author: Flexo,
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).

 29
Author: paxdiablo,
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.

 9
Author: curiousguy,
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