88 votes

Allouer correctement des tableaux multidimensionnels

Le but de cette question est de fournir un cadre de référence sur la façon de répartir correctement multi-dimensions des tableaux dynamiquement en C. C'est un sujet souvent mal compris et mal expliqué, même dans certains de programmation C livres. Par conséquent, même expérimenté C programmeurs lutte pour obtenir ce droit.


J'ai appris de ma programmation de l'enseignant/livre/tutoriel-ce la bonne façon d'allouer dynamiquement un tableau multidimensionnel est par l'utilisation de pointeur de pointeurs.

Cependant, plusieurs personnalités représentant les utilisateurs sur ALORS maintenant, dites-moi que c'est faux et de mauvaise pratique. Ils disent que le pointeur de pointeurs ne sont pas des tableaux, que je ne suis pas réellement d'allouer des tableaux et que mon code est inutilement lente.

C'est ainsi que j'ai appris à allouer des multi-dimensions des tableaux:

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

int** arr_alloc (size_t x, size_t y)
{
  int** pp = malloc(sizeof(*pp) * x);
  assert(pp != NULL);
  for(size_t i=0; i<x; i++)
  {
    pp[i] = malloc(sizeof(**pp) * y);
    assert(pp[i] != NULL);
  }

  return pp;
}

int** arr_fill (int** pp, size_t x, size_t y)
{
  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      pp[i][j] = (int)j + 1;
    }
  }

  return pp;
}

void arr_print (int** pp, size_t x, size_t y)
{
  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      printf("%d ", pp[i][j]);
    }
    printf("\n");
  }
}

void arr_free (int** pp, size_t x, size_t y)
{
  (void) y;

  for(size_t i=0; i<x; i++)
  {
    free(pp[i]);
    pp[i] = NULL;
  }
  free(pp);
  pp = NULL;
}


int main (void)
{
  size_t x = 2;
  size_t y = 3;
  int** pp;

  pp = arr_alloc(x, y);
  pp = arr_fill(pp, x, y);
  arr_print(pp, x, y);
  arr_free(pp, x, y);

  return 0;
}

Sortie

1 2 3
1 2 3

Ce code fonctionne très bien! Comment pourrait-il être mauvais?

0voto

Basile Starynkevitch Points 67055

C n'ont pas de tableaux multidimensionnels. Mais vous pourriez avoir des tableaux de tableaux (ou d'autres agrégats) et des tableaux de pointeurs.

Une approche possible consiste à raisonner avec certains type abstrait de données (peut-être à l'aide de flexibles membres du groupe, qui est une mise en œuvre truc, et vous pouvez utiliser d'autres approches) comme dans cette réponse.

On ne peut pas proposer tout type abstrait de données, car cela dépend du texte de vos devoirs, que nous n'avons pas. Vous devez concevoir votre type abstrait de données (sur un morceau de papier), et plus tard pour la mettre en œuvre.

Une fois que vous avez répertoriés (sur un support papier ou sur un conseil) l'ensemble des opérations nécessaires sur votre ADT, leur mise en œuvre est simple.

Ce code fonctionne très bien! Comment pourrait-il être mauvais?

Cette phrase est incohérente (mauvaise w.r.t. quelles sont les spécifications?) ...

Je recommande pour compiler tous les avertissements et les informations de débogage (par exemple, avec gcc -Wall -Wextra -g avec GCC), afin d'améliorer votre code jusqu'à ce que vous n'obtenez pas de mises en garde, pour utiliser le débogueur gdb (pour comprendre ce qui se passe dans votre programme) et d'autres outils comme valgrind.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X