2015-05-07 9 views
7
#include <stdio.h> 
#include <stdlib.h> 

struct Point { 
    double x; 
}; 

void test(struct Point **a, int len) 
{ 
    int i; 

    printf("a = %p\n", a); 
    for (i = 0; i < len; ++i) 
     printf("%f\n", a[i]->x); 
} 

int main() 
{ 
    int i; 
    int len = 4; 

    struct Point *P; 

    P = malloc(len*sizeof(struct Point)); 

    for (i = 0; i < len; ++i) { 
     P[i].x = i; 
     printf("%f\n", P[i].x); 
    } 
    printf("&P = %p\n", &P); 
    test(&P, len); 

    return 0; 
} 

Sto provando a passare una matrice di strutture a una funzione (voglio passare un puntatore all'array, non creare una copia). Quando provo a utilizzare l'array all'interno della funzione, ottengo una violazione di accesso. Qual è il modo corretto per farlo? Che cosa sto facendo di sbagliato? a == &P, quindi dovrebbe funzionare, giusto?Errore durante il passaggio del puntatore all'array di strutture

+1

Ma 'P' già * è * un puntatore, punta al primo elemento della memoria allocata (la matrice). Passando il puntatore, così com'è, non stai copiando nulla se non il puntatore effettivo. –

+5

'printf ("% f \ n ", (* a) [i] .x);' – BLUEPIXY

risposta

5

Perché vuoi un struct Point **? È possibile riscrivere la stessa

void test(struct Point *a, int len) 
{ 
    //some stuff 
    printf("%f\n", a[i].x); 

} 

e chiamarlo come

test(P, len); 

In questo modo, secondo me, il requisito

voglio passare un puntatore alla matrice

si incontra anche #.


(#) NOTA: Per essere rigorosi, qui si passa il puntatore al primo elemento della matrice, tuttavia, il comportamento confronta uguali. Grazie a Mr. @alk per il commento.

+0

Grazie, Quindi, per sicurezza, non viene fatta nessuna copia quando ci si trova nella funzione, e le eventuali modifiche apportate all'array persistono anche dopo il ritorno della funzione? – user1801359

+0

To nitpick: il modo in cui si mostra un puntatore al primo elemento di un array viene passato. Questo è diverso da un puntatore a un array, quest'ultimo sarebbe 'struct Point (* pa) [len]'. – alk

+0

@alk Molto vero signore. Puoi suggerire le parole appropriate per modificare la mia risposta? –

3

Passando &p operato test significa che si passa un puntatore al primo elemento di un array di un elemento di tipo struct Point *. Pertanto, solo a[0] è valido (e quindi a[0]->x) e tutti gli altri a[i] non sono accessibili. Questo invocherà un comportamento indefinito.

Modificare a[i]->x a a[0][i].x o (*a)[i].x nella funzione test.

L'utilizzo del puntatore del puntatore in questo caso non è degno. Vale la pena utilizzarlo se il puntatore passato viene modificato nella funzione e si prevede che tale modifica venga vista nel chiamante.

+2

Oppure '(* a) [i] -> x' –

+3

o meglio' (* a) [i] .x ' –

+2

@WojciechFrohmberg, non dovrebbe essere quello che JoachimPileborg ha suggerito nel commento sopra? –

1

La matrice deve essere passata utilizzando il parametro struct Point *a. Quando si incrementa a, il puntatore si sposterà di sizeof(struct Point).

void test(const struct Point *a, int len) 
{ 
    ... 
} 
1

Altre risposte che offrono una migliore alternatives.But metto questo qui per aiutare chiunque (me) capire perché è sbagliato.

enter image description here

0

Desidero passare un puntatore alla matrice,

Prendendo il vostro requisito letteralmente lo si fa in questo modo:

void test(size_t len, struct Point (*a)[len]) 
{ 
    size_t i; 

    printf("a = %p\n", (void *) a); 

    for (i = 0; i < len; ++i) 
    printf("%f\n", (*a)[i].x); 
} 

e chiamarlo in questo modo:

size_t len = 4; 
struct Point * p = malloc(len * sizeof *p); 

for (i = 0; i < len; ++i) { 
    p[i].x = i; 
    printf("%f\n", p[i].x); 
} 

printf("p = %p\n", (void *) p); 
printf("&p = %p\n", (void *) &p); 

test(len, &p); 

Si potrebbe anche implementare la stessa funzionalità (looping sugli elementi della matrice) andando nel modo proposto da Sourav Ghosh's answer. Quindi passarebbe un puntatore all'elemento 1 st dell'array, quindi un puntatore all'array stesso.

+0

Già risolto. @haccks Grazie, comunque. – alk

Problemi correlati