bonne façon de retourner un tableau à deux dimensions à partir d’une fonction c

J’ai essayé ça mais ça ne marchera pas:

#include  int * retArr() { int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; return a; } int main() { int a[3][3] = retArr(); return 0; } 

Je reçois ces erreurs:

Erreur 3 Erreur C2075: ‘a’: l’initialisation du tableau nécessite des accolades
4 IntelliSense: le type de valeur renvoyé ne correspond pas au type de fonction

Qu’est-ce que je fais mal?

Une struct est une approche:

 struct t_thing { int a[3][3]; }; 

il suffit ensuite de renvoyer la structure par valeur.

Exemple complet:

 struct t_thing { int a[3][3]; }; struct t_thing retArr() { struct t_thing thing = { { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} } }; return thing; } int main(int argc, const char* argv[]) { struct t_thing thing = retArr(); ... return 0; } 

Le problème typique auquel vous êtes confronté est le suivant: int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; dans votre exemple, fait référence à la mémoire qui est récupérée après le retour de la fonction. Cela signifie que votre appelant ne peut pas lire en toute sécurité (comportement non défini).

D’autres approches impliquent de passer le tableau (que l’appelant possède) en tant que paramètre de la fonction ou de créer une nouvelle atsortingbution (par exemple, à l’aide de malloc ). La structure est intéressante car elle peut éliminer de nombreux pièges, mais elle n’est pas idéale pour tous les scénarios. Vous éviterez d’utiliser une structure par valeur lorsque la taille de la structure n’est pas constante ou très grande.

 #include  int** retArr() { static int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; return a; } int main() { int** a = retArr(); return 0; } 

Vous pouvez également spécifier la variable renvoyée sous forme statique. Vous devez également déclarer la variable a in main comme étant juste int ** (et ne pas spécifier les dimensions).

Plusieurs problèmes:

Tout d’abord, vous ne pouvez pas initialiser un tableau à partir d’un appel de fonction; la définition du langage ne le permet tout simplement pas. Un tableau de caractères peut être initialisé avec un littéral de chaîne, tel que

 char foo[] = "This is a test"; 

un tableau de wchar_t , char16_t ou char32_t peut être initialisé avec un littéral de chaîne large, mais l’initialiseur doit être une liste de valeurs char32_t par des accolades.

Deuxièmement, vous avez une incompatibilité de type; sauf s’il s’agit de l’opérande de sizeof ou des opérateurs unary & , ou si un littéral de chaîne est utilisé pour initialiser un autre tableau dans une déclaration, une expression de type “tableau de N éléments” sera convertie en une expression de type ” pointeur sur T “, et la valeur de l’expression sera l’adresse du premier élément;

Dans la fonction retArr , le type de a dans l’expression est “tableau à 3 éléments d’un tableau à 3 éléments de int “; selon la règle ci-dessus, cela sera converti en une expression de type “pointeur vers un tableau d’ int de 3 éléments” ou int (*)[3] :

 int (*retArr())[3] { int a[3][3] = ...; return a; } 

mais comme le fait remarquer Brendan, une fois que retArr sorti, retArr n’existe plus; la valeur de pointeur renvoyée est invalide.

Nous pouvons le résoudre en utilisant l’allocation mémoire / mémoire Heap à l’aide de stdlib:

L’allocation de mémoire à l’aide de stdlib peut être effectuée par malloc et calloc.

création de tableau :

  •  int ** arr=( int * * ) malloc ( sizeof ( int * ) * 5 ); 

    est pour allouer 5 lignes.

  •  arr[i]=(int *)malloc(sizeof(int)*5); 

    est pour allouer 5 colonnes dans chaque ligne “i”.

  • Nous avons donc créé arr [5] [5].

tableau de retour:

  •  return arr; 

Nous avons juste besoin d’envoyer ce pointeur qui est responsable de l’access à ce tableau comme ci-dessus.

 #include #include int **return_arr() { int **arr=(int **)malloc(sizeof(int *)*5); int i,j; for(i=0;i<5;i++)//checking purpose { arr[i]=(int *)malloc(sizeof(int)*5); for(j=0;j<5;j++) { arr[i][j]=i*10+j; } } return arr; } int main() { int **now; now=return_arr(); int i,j; for(i=0;i<5;i++) { for(j=0;j<5;j++) { printf("%d ",now[i][j]); } printf("\n"); } return 0; } 

Pour ça:

 int * retArr() { int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; return a; } 

Le tableau a une scope locale et est détruit dès que vous quittez la fonction. Cela signifie que return a; renvoie en fait un pointeur qui pend.

Pour résoudre ce problème, placez le tableau dans une étendue globale ou utilisez malloc() et copiez-le dans l’espace alloué.

Doit retourner int** , pas int .