Malloc ou définition de tableau normale?

Quand dois-je utiliser malloc au lieu de la définition de tableau normale en C?

Je ne peux pas comprendre la différence entre:

int a[3]={1,2,3} int array[sizeof(a)/sizeof(int)] 

et:

 array=(int *)malloc(sizeof(int)*sizeof(a)); 

En général, utilisez malloc() lorsque:

  • le tableau est trop grand pour être placé sur la stack
  • la durée de vie du tableau doit survivre à la scope où il est créé

Sinon, utilisez un tableau alloué par stack.

 int a[3]={1,2,3} int array[sizeof(a)/sizeof(int)] 

Si elles sont utilisées en tant que variables locales, a array et a array seront alloués sur la stack. L’allocation de stack a ses avantages et inconvénients:

  • pro: c’est très rapide – il suffit d’une opération de soustraction de registre pour créer de la stack et d’une opération d’addition de registre pour le récupérer
  • con: la taille de la stack est généralement limitée (et également corrigée au moment du lien sous Windows)

Dans les deux cas, le nombre d’éléments dans chaque tableau est une constante de compilation: 3 est évidemment une constante, tandis que sizeof(a)/sizeof(int) peut être calculé au moment de la compilation car la taille de a et la taille de int sont toutes deux int connu au moment où le array est déclaré.

Lorsque le nombre d’éléments est connu uniquement au moment de l’exécution ou que la taille du tableau est trop grande pour tenir en toute sécurité dans l’espace de stack, l’atsortingbution de segment de mémoire est utilisée:

 array=(int *)malloc(sizeof(int)*sizeof(a)); 

Comme déjà indiqué, il devrait s’agir de malloc(sizeof(a)) car la taille de a correspond déjà au nombre d’octets nécessaires et non au nombre d’éléments. Une multiplication supplémentaire par sizeof(int) n’est donc pas nécessaire.

L’allocation et la désallocation de tas sont des opérations relativement coûteuses (comparées à une allocation de stack) et elles doivent être soigneusement comparées aux avantages qu’elles procurent, par exemple dans un code appelé de multiples fois dans des boucles serrées.

Les compilateurs C modernes prennent en charge la version C99 de la norme C qui introduit les tableaux de longueur variable (ou VLA), qui ressemblent à des fonctionnalités similaires disponibles dans d’autres langues. La taille de VLA est spécifiée au moment de l’exécution, comme dans ce cas:

 void func(int n) { int array[n]; ... } 

array est toujours alloué sur la stack comme si la mémoire du tableau avait été allouée par un appel à alloca(3) .

Vous devez certainement utiliser malloc () si vous ne voulez pas que votre tableau ait une taille fixe. En fonction de ce que vous essayez de faire, il est possible que vous ne sachiez pas à l’avance combien de mémoire vous allez avoir besoin pour une tâche donnée ou que vous devez redimensionner dynamicment votre tableau au moment de l’exécution, par exemple, vous pouvez l’agrandir s’il y a plus de données. Ce dernier peut être fait en utilisant realloc () sans perte de données.

Au lieu d’initialiser un tableau comme dans votre message d’origine, vous devez simplement initialiser un pointeur sur un entier, comme.

 int* array; // this variable will just contain the addresse of an integer sized block in memory int length = 5; // how long do you want your array to be; array = malloc(sizeof(int) * length); // this allocates the memory needed for your array and sets the pointer created above to first block of that region; int newLength = 10; array = realloc(array, sizeof(int) * newLength); // increase the size of the array while leaving its contents intact; 

Votre code est très étrange.

La réponse à la question dans le titre est probablement quelque chose comme “utilisez des tableaux automatiquement alloués lorsque vous avez besoin d’assez petites quantités de données qui sont de courte durée, des allocations de tas utilisant malloc() pour toute autre chose”. Mais il est difficile de trouver une réponse exacte, cela dépend beaucoup de la situation.

Vous ne savez pas pourquoi vous affichez d’abord un tableau, puis un autre tableau qui tente de calculer sa longueur à partir du premier et enfin un appel à malloc() qui tente de faire la même chose.

Normalement, vous avez une idée du nombre d’éléments souhaités, plutôt qu’un tableau existant dont vous voulez imiter la taille.

La deuxième ligne est meilleure comme:

 int array[sizeof a / sizeof *a]; 

Nul besoin de répéter une dépendance sur le type d’ a , ce qui précède définira un array comme un tableau d’ int avec le même nombre d’éléments que le tableau a . Notez que cela ne fonctionne que s’il s’agit bien d’un tableau.

En outre, la troisième ligne devrait probablement être:

 array = malloc(sizeof a); 

Pas besoin d’être trop intelligent (surtout depuis que vous vous êtes trompé) à propos de l’argument sizeof , et pas besoin de malloc() valeur de retour de malloc() .