2010-08-18 5 views
1

J'ai functon cette liste de conversion dans le tableau:liste Convertir en tableau

void* list_to_array(SList* list) 
{ 
    int i; 
    int array_size = list_get_length(list); 

    void* array[array_size]; 

    for (i = 0; i < array_size; i++) 
    { 
     array[i] = list_get_n_data(list,i); 
    } 

    return *array; 
} 

Mais quand je tente de le tester:

int* a = (int*)list_to_array(list); 
printf("%d" (int)a); 

il est ok. Je vois le premier élément. Mais quand je tente d'obtenir la deuxième ou troisième élément:

int* a = (int*)list_to_array(list); 
a++; 
printf("%d" (int)a); 

Je vois premier élément + 4. si je tente obtenir troisième élément que je vois la première valeur de l'élément + 8 et etc ... Pourquoi? Qu'est-ce qui ne va pas?

Merci

+1

vous retournez le premier élément du tableau uniquement. Sans connaître le reste de vos affaires, rien ne peut être dit (sauf que vous ne devriez même pas penser à renvoyer des pointeurs qui pointent vers des variables locales). –

Répondre

6

Vous retournez un pointeur vers un emplacement de mémoire de la pile. Cette zone de mémoire n'est plus valide une fois la fonction retournée.

En outre, au lieu de renvoyer réellement un pointeur sur le tableau, vous renvoyez le premier élément dans le tableau. Le code suivant retournera 1, pas un pointeur sur le tableau.

int array[] {1, 2, 3, 4}; 
return *array 

Vous avez probablement seulement besoin de faire des changements minimes votre code pour le faire fonctionner.

void** array = (void **) malloc(sizeof(void *) * array_size); 
... 
return array; 

Assurez-vous que vous relâchez la mémoire que la mémoire utilisée pour array lorsque vous avez terminé avec elle.

void **array = list_to_array(list); 
// Use array 
... 
// Finished with array 
free(array); 
+1

Il a écrit: ** retour * tableau; ** Peut-être que c'est quelque chose de valable? Nous ne saurons pas de son code. –

+0

Merci pour votre réponse. Comment puis-je retourner tableau? – 0xAX

+0

+1 Allouer de l'espace mémoire avec malloc() assurera que votre tableau continue d'exister même après le retour de la fonction. – karlphillip

1

Lorsque vous augmentez le pointeur int* a par 1, il augmenterait en fait par sizeof(int), qui est - sur la plupart des systèmes, au moins - 4.

Donc, si

int* a = 0x40b8c438 

puis

a + 1 
     = ((void*) a) + sizeof(int) 
     = 0x40b8c43c 

et

a + 2 
     = ((void*) a) + sizeof(int) * 2 
     = 0x40b8c440 
0

Vous avez trois problèmes ici. La première est triviale, vous renvoyez le premier élément du tableau avec return *array, quand vous voulez dire que vous voulez renvoyer un pointeur vers le premier élément du tableau avec return array. N'arrêtez pas ici! La seconde est que vous augmentez votre pointeur de 1, plutôt que par la taille des données que vous pointez. Cela vous donnera des résultats erronés. Le troisième problème est beaucoup plus grave:
Vous allouer de la mémoire pour votre tableau sur cette ligne:

void* array[array_size]; 

Cette mémoire est allouée sur la pile, et cette mémoire n'est alloué plus lorsque vous revenez de la fonction. Lorsque vous faites référence à la fin de cette mémoire avec la ligne:

int* a = (int*)list_to_array(list); 

une pointe vers une région sur la pile qui n'est plus utilisé. Vous obtenez des résultats quelque peu raisonnables avec le code que vous avez, mais si vous modifiez la pile après le retour de votre fonction, un pointera sur la nouvelle mémoire.Par exemple, si vous utilisez le code suivant:

int* a = (int*)list_to_array(list1); 
int* b = (int*)list_to_array(list2); 
printf("%d" (int)a); 

Vous (probablement) voir le premier élément de b. Ce n'est pas garanti - Vous pouvez également obtenir une erreur de segmentation. L'autre code entre l'affectation à a et son utilisation écrasera également le contenu de la mémoire que vous avez accédé dans votre instruction printf.

Vous devez allouer votre mémoire avec la même portée que a. Le problème le moins grave est le fait que vous n'augmentez pas votre pointeur de la bonne quantité. Vous devez utiliser l'opérateur sizeof(). Alternativement, vous pouvez accéder à vos éléments de tableau avec [].

int* a = (int*)list_to_array(list, array); 
printf("%d" a[1]); //Prints second element of a 
a += sizeof(int) * 2; 
printf("%d" (int)a); //Prints third element of a 
0

Vous devez être prudent avec les pointeurs, déclarer cette façon:

int main() 
{ 
    int *array; 
    int i; 
    i = size(list); 
    array = list_to_array(list, i); 

... 
free(array); 
} 

int  size(t_list *list) 
{ 
    int i; 

    i = 0; 
    while (list) 
    { 
     i++; 
     list = list->next; 
    } 
    return (i); 
} 

int  *list_to_array(t_list *list, int size) 
{ 
    int  *array; 
    int  i; 
    t_list *temp; 

    i = 0; 
    if (list == NULL) 
     return (NULL); 
    array = (int*)malloc(sizeof(int) * size + 1); 
    temp = list; 
    while (temp) 
    { 
     array[i] = temp->data; 
     temp = temp->next; 
     i++; 
    } 
    return (array); 
} 
Questions connexes