Pourquoi, ou quand, avez-vous besoin d'allouer dynamiquement de la mémoire en C?
Allocation dynamique de la mémoire est un thème très important dans la programmation en C. Cependant, j'ai été incapable de trouver une bonne explication de ce que cela nous permet de faire, ou pourquoi elle est nécessaire.
Ne peut-on pas déclarer les variables et les structures et ne jamais avoir à utiliser malloc()?
Comme une note de côté, quelle est la différence entre:
ptr_one = (int *)malloc(sizeof(int));
et
int *ptr_one = malloc(sizeof(int));
source d'informationauteur user2517777
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser la dynamique de la mémoire lorsque:
On ne sait pas toujours comment beaucoup de mémoire, vous aurez besoin de mettre de côté au moment de la compilation. Imaginez le traitement d'un fichier de données (série chronologique des températures, par exemple), où le nombre d'enregistrements dans le fichier n'est pas fixe. Vous pourriez avoir aussi peu que 10 dossiers ou autant que 100000. Si vous voulez lire toutes les données en mémoire pour le processus, vous ne pouvez pas savoir la quantité de mémoire à allouer jusqu'à ce que vous lire le fichier. Si le fichier est structuré de sorte que la première valeur est le nombre d'enregistrements, vous pourriez faire quelque chose comme ceci:
Parfois, vous devez allouer un très grand objet, quelque chose comme
En supposant un entier de 4 octets, ce groupe aura besoin de 4 go. Malheureusement, la pile d'images (où les variables locales sont conservés sur la plupart des architectures) ont tendance à être beaucoup plus petit, donc essayer d'allouer beaucoup de mémoire peut conduire à une erreur d'exécution (et le fait habituellement). La dynamique de mémoire en pool (un.k.un. le tas) est généralement beaucoup plus grande que la pile, beaucoup moins un cadre de pile. donc pour quelque chose de désagréable, vous devez écrire quelque chose comme
C'est encore possible pour une demande comme ça à l'échec; si votre tas est fragemented assez, vous ne pouvez pas avoir un seul bloc contigu assez grand pour hande la demande. Si nécessaire, vous pouvez le faire au coup par coup de répartition; les lignes ne seront pas nécessairement adjacents dans la mémoire, mais il est plus probable que vous serez en mesure de saisir toute la mémoire dont vous avez besoin:
Et enfin, la mémoire dynamique qui permet de construire des conteneurs qui peuvent grandir et rétrécir à mesure que vous ajoutez ou supprimez des données, tels que les listes, les arbres, les files d'attente, etc. Vous pouvez même construire votre propre "chaîne" type de données qui peut croître que l'ajout de personnages (similaire à la
string
type en C++).L'allocation dynamique est nécessaire lorsque vous ne savez pas le pire des cas requise pour la mémoire. Ensuite, il est impossible d'allouer de manière statique la mémoire nécessaire, parce que vous ne savez pas combien vous aurez besoin.
Même si vous savez le pire des cas, elle peut encore être souhaitable d'utiliser l'allocation dynamique de la mémoire. Il permet pour la mémoire système pour être utilisés plus efficacement par plusieurs processus. Tous les processus de manière statique commettre leur pire des cas, la configuration de la mémoire, mais qui impose un plafond sur le nombre de processus en cours d'exécution peut exister sur le système. Si elle n'est jamais le cas que tous les processus utilisent le pire des cas, dans le même temps, le système de mémoire fonctionne en permanence sous-utilisées, ce qui est un gaspillage de ressources.
À vos côtés question, vous ne devraient pas jeter le résultat d'un appel à
malloc()
en C. Il peut cacher le bug de l'absence de déclaration (implicite des déclarations ont été autorisés avant le C. 99), et les résultats dans un comportement indéfini. Préfère toujours prendre le résultat demalloc()
sans un plâtre.malloc()
est déclarée pour retournervoid *
et en C, une conversion entrevoid *
et un autre type de pointeur est toujours autorisée (modulo type de qualificatifs commeconst
).Voir cette.
Le pool de mémoire (ou plus communément le tas) est très grande en comparaison de la pile. Tenir compte de ces deux exemples pour expliquer pourquoi il est utile d'utiliser le pool de mémoire sur la pile:
1. Que faire si vous avez défini un tableau et je voulais que ça persistent entre de multiples pile d'images? Bien sûr, vous pourriez déclarer comme une variable globale et il sera stocké dans les données globales de la section de la mémoire, cependant cela permet d'obtenir des encombré que votre programme devient plus grand et plus. Sinon, vous pouvez les stocker sur la mémoire de la piscine.
... ce serait toutefois pas travail si vous avez défini votre tableau sur la pile. Raison d'être, une fois un frame de pile est sauté toutes les adresses de mémoire peut être utilisé par un autre cadre de pile (et donc écrasé), tandis que l'utilisation de la mémoire à partir du pool de mémoire persisteront jusqu'à ce que
free
d par l'utilisateur (vous ou le client).2. Que faire si vous avez voulu mettre en place un tableau dynamique pour gérer la lecture de l'arbitraire d'un grand séquence de nombres? Vous ne seriez pas capable de faire cela de la définition de votre tableau sur la pile, vous devez utiliser le pool de mémoire. Rappelons qu'il est extrêmement commun (et fortement recommandé, sauf si vous explicitement besoin de copier une structure (struct) en passant un pointeur vers une struct, jamais la structure elle-même (comme ils peuvent être assez grande). Envisager cette petite mise en œuvre d'un tableau dynamique:
... sur la ligne de
[oo]
que si ce ont été définis sur la pile, puis une fois cette trame de pile est sauté toutes les adresses de la mémoire pour le tableau ne serait plus attribué. Sens, un autre cadre de pile (probablement le prochain) sera à l'aide de ces adresses mémoire (ou un sous-ensemble de celui-ci).Remarque: De mon bout de code
ptr_block
est stockée dans la pile: d'où&ptr_block
est une pile d'adresses, mais la valeur deptr_block
est quelque part dans le pool de mémoire.