Warum entsteht ein Segmentierungsfehler?

7
%Vor%     
avd 15.03.2010, 15:21
quelle

6 Antworten

10
  

Angenommen, Sie deklarieren:       int arr [10] [20];     Welcher Typ ist arr?
  Du denkst vielleicht, dass es int ** ist, aber das ist falsch.

     

Es ist tatsächlich vom Typ int (*)[20] , wenn es abklingt (wie wenn Sie es an eine Funktion übergeben);
Array-Verfall gilt nur einmal.

Details hier p>

Betrachten Sie nun Folgendes,

%Vor%

Ausgabe:

  

$ gcc fdsf.c & amp; & amp; ./a.out
  0
  1

  

arr und arr + 1 zeigen auf ein Array mit 20 ganzen Zahlen.

     

arr + 0 - & gt; int int int ... int (20 ints, zusammenhängend)
  [0] [0] [0] [1]
  arr + 1 - & gt; int int int ... int (20 ints, zusammenhängend)
  [1] [0] [1] [1]

    
N 1.1 15.03.2010, 15:28
quelle
7

So sieht ein int[2][2] im Speicher aus:

int[2] int[2]

Das heißt, auf ein Array folgt unmittelbar ein anderes Array.

So sieht ein int[2] im Speicher aus:

int int

Das heißt, auf ein int folgt sofort ein weiteres int.

Also, hier ist auch, wie ein int[2][2] im Speicher aussieht:

%Vor%

Wenn du arr auf int** wirfst, werde ich das Ergebnis p aufrufen. Dann zeigt es auf die gleiche Erinnerung. Wenn Sie p[1][1] ausführen, erhalten Sie arr[1][1] nicht. Was das Programm stattdessen tut ist, liest es den Wert bei p[1] , passt das um die Größe eines int an, und dereferenziert es . Wenn dieser zweite int enthalten ist, sagen wir, den Wert "21" dann haben Sie gerade versucht, den Zeiger "25" dereferenzieren (wenn int 4 Bytes ist). Das ist nicht richtig.

Arrays sind nicht dasselbe wie Zeiger, und 2D-Arrays sind sicherlich nicht dasselbe wie Zeiger auf Zeiger.

    
Steve Jessop 15.03.2010 15:28
quelle
6

Weil foo einen Zeiger auf einen Zeiger auf int erwartet und Sie ihm einen Zeiger auf ein Array von 20 int übergeben. Casting wird nicht die Tatsache ändern, dass es nicht der richtige Typ ist.

    
AProgrammer 15.03.2010 15:23
quelle
5

Wenn Sie es so ändern, erhalten Sie das erwartete Ergebnis:

%Vor%     
Lucas 15.03.2010 15:49
quelle
4

foo muss die Array-Größe kennen (nun, zumindest die zweite Array-Dimension, die erste wird nicht benötigt), sonst kann sie nicht die notwendige Zeigerarithmetik für die [1][1] ausführen.

    
Peter Alexander 15.03.2010 15:25
quelle
1

Problem ist, dass int arr[20][20] für 2d Array bedeutet, dass dieses Array als 1d Array gespeichert wird und Zeilen nacheinander gespeichert werden. Wenn Sie die Indizierung auf int **arr durchführen, nehmen Sie tatsächlich das zweite Element aus der ersten Zeile des Arrays, dann dereferenzieren Sie es und nehmen das erste Element dort.

    
Andrey 15.03.2010 15:27
quelle

Tags und Links