2010-06-01 15 views
8

Eventuali duplicati:
casting char[][] to char** causes segfault?int ** vs int [FILE] [COLS]

Ho un array 2D dichiarato in questo modo:

int arr[2][2]={ {1,2},{3,4}}; 

Ora, se Faccio:

int ** ptr=(int**) arr; 

e:

cout<<**ptr; 

sto ottenendo un errore di segmentazione (con g ++ - 4.0).

Perché così? Non dovrebbe stampare il valore 1 (uguale a arr[0][0])?

+3

penso che ci sia un grande regola in C++: "Se dovete lanciare, non te lo puoi permettere" http://blogs.msdn.com/b/oldnewthing/archive/2009/10/23/9911891.aspx – SergGr

risposta

1

Si sta tentando di assegnare una variabile a doppio puntatore a un array ... questo è stato coperto esaustivamente, vedere here per informazioni su questo. Inoltre, dal momento che hai dichiarato

 
int arr[2][2] = ...; 

e poi tenta di assegnare arr ad un doppio puntatore

 
int ** ptr = ... ; 

che è garantito a non funzionare, quindi un errore di segmentazione.Inoltre, tale affermazione int ** ptr=(int**) arr; è in realtà cast in un tipo (ad esempio [] []) in un altro tipo (ad esempio **) nonostante siano di tipo "int". Sono entrambi diversi e il compilatore che interpreteranno in modo molto diverso ...

che si possa fare in questo modo:

 
int *ptr = &arr; 

Ora *(ptr + 1) farà riferimento alla riga di indice 0, *(ptr + 2) farà riferimento al 1 'st row e così via. L'unico onere su di te è non oltrepassare i marker di dove si può verificare arr altrimenti può verificarsi un errore di segmentazione ...

0

Prova

int *ptr = arr; 

Più Spiegazione:

Si dovrebbe assegnare un indirizzo al puntatore, in modo che possa essere derefenced (intendo * operatore). Quello che fai è, puntando ptr alla cella di memoria che ha l'indirizzo a [0] [0]. Pertanto, si ottiene un errore di segmentazione.

5

Non è possibile trasmettere un array lineare a un tipo di puntatore a puntatore, poiché int** non contiene gli stessi dati int[][]. Il primo contiene i puntatori ai puntatori ai pollici. Il secondo contiene una sequenza di interi, nella memoria lineare.

+0

Bene, si "può", come dimostra l'OP. Devi solo fare un reinterpret_cast, cosa che l'OP inconsapevolmente ha fatto perché sta usando cast in stile C. Come in tutti questi casi, ovviamente il risultato dell'accesso al nuovo puntatore è UB. La morale che l'OP dovrebbe ottenere è: usa i cast di C++ in C++. –

1

No, int ** è un puntatore a un puntatore a un int, ma un array 2D è un array di matrici e &(arr[0][0]) è un puntatore a un int.

Credo che si dovrebbe fare questo:

int *ptr = arr; 
cout<<*ptr; 

o questo:

int *ptr = &arr[0][0]; 
cout<<*ptr; 
2

Quello che fai significa che ora la creazione di array di puntatori dove ogni puntatore è stato colato esplicitamente. Pertanto, si dispone di una serie di puntatori come (0x00001, 0x00002, 0x00003 and 0x00004).

In caso di riferimento, questi indicatori causano il tuo segfault.

0

int arr[2][2] non è un array di array: è un singolo array 2D. In memoria, è indistinguibile da int arr[4]

cosa si vuole veramente è

int (*ptr)[2] = arr; 
+0

Formalmente, * è * una matrice di matrici. Ma sì, dal momento che gli array sono disposti in modo contiguo senza il padding consentito, un 'int [2] [2]' è effettivamente disposto esattamente come un 'int [4]' in memoria. – caf