Dans quelles circonstances malloc peut-il retourner NULL?

cela ne m'est jamais arrivé, et j'ai des programmes depuis des années maintenant.

Quelqu'un peut-il me donner un exemple d'un programme non trivial dans lequel malloc en fait pas de travail?

je ne parle pas de la mémoire de l'épuisement: je cherche le cas simple lorsque vous attribuez juste un bloc de mémoire dans une taille limite donnée par l'utilisateur, disons un entier, causes malloc à l'échec.

24
demandé sur RanZilber 2012-02-01 23:01:17
la source

9 ответов

Oui.

Juste essayer d' malloc plus de mémoire que ce que votre système peut fournir (soit en épuisant votre espace d'adresse, ou mémoire virtuelle - selon la plus petite des deux).

malloc(SIZE_MAX)

va probablement le faire. Si pas, répéter à quelques reprises jusqu'à ce que de vous lancer.

14
répondu Useless 2012-02-01 23:22:30
la source

vous devez faire un peu de travail dans les systèmes embarqués, vous obtiendrez souvent NULL retourné là : -)

il est beaucoup plus difficile de manquer de mémoire dans les systèmes modernes de stockage d'adresses massives, mais c'est tout à fait possible dans les applications où vous traitez de grandes quantités de données, comme les bases de données SIG ou en mémoire, ou dans les endroits où votre code buggy entraîne une fuite de mémoire.

mais il n'a vraiment pas d'importance si vous n'avez jamais éprouvé avant - la norme il dit que ça peut arriver donc tu devrais t'en occuper. Je n'ai pas été heurté par une voiture dans les dernières décennies non plus, mais cela ne signifie pas que je erre à travers les routes sans regarder en premier.

Et re votre edit:

Je ne parle pas de l'épuisement de la mémoire, ...

très définition de l'épuisement de la mémoire est malloc ne pas vous donner l'espace désiré. Peu importe que ce soit causé par l'attribution de toute la mémoire disponible, ou tas fragmentation signifie que vous ne pouvez pas obtenir un bloc contigu même si l'ensemble de tous les blocs libres dans l'arène de la mémoire est plus élevé, ou limiter artificiellement votre utilisation de l'espace d'adresse tel en utilisant la fonction conforme aux normes:

void *malloc (size_t sz) { return NULL; }

la norme C ne fait pas de distinction entre modes de l'échec, seulement qu'il réussit ou échoue.

21
répondu paxdiablo 2014-09-11 10:59:45
la source

tout programme écrit en c qui a besoin d'allouer dynamiquement plus de mémoire que le système D'exploitation ne le permet actuellement.

Pour le plaisir, si vous utilisez ubuntu, tapez

 ulimit -v 5000

tout programme que vous exécutez va très probablement planter (en raison d'une défaillance de malloc) que vous avez limité la quantité de mémoire disponible à un processus quelconque à une quantité Pity.

8
répondu RussS 2013-09-02 19:27:05
la source

sauf si votre mémoire est déjà complètement réservée (ou fortement fragmenté), la seule façon d'avoir malloc() retour NULLpointeur est à la demande de l'espace de la taille zéro:

char *foo = malloc(0);

citant la norme C99, §7.20.3, sous-section 1:

si la taille de l'espace demandé est zéro, le behavior est implémentationdefined: soit un pointeur nul est retourné, soit le behavior est comme si la taille était valeur non nulle, sauf que la pointeur retourné ne doit pas être utilisé pour accéder à un objet.

En d'autres termes, malloc(0) retour NULL-pointeur ou pointeur valide à zéro octets alloués.

5
répondu Philip 2012-02-02 12:29:15
la source

il suffit de vérifier la page de manuel de malloc.

On success, un pointeur vers le bloc mémoire alloué par la fonction.

Le type de ce pointeur est toujours void*, qui peut être converti dans le type de pointeur de données afin d'être dereferenceable.

Si la fonction n'a pas attribué le bloc de mémoire demandé, un pointeur nul est retourné.

4
répondu starrify 2012-02-01 23:05:55
la source

puisque vous avez demandé un exemple, voici un programme qui verra (éventuellement)malloc retour NULL:

perror();void*malloc();main(){for(;;)if(!malloc(999)){perror(0);return 0;}}

Quoi? Vous n'aimez pas le code délibérément masqué? ;) (S'il tourne pendant quelques minutes et ne s'écrase pas sur votre machine, le tuer, changer 999 à un plus grand nombre et réessayez.)

EDIT: si cela ne fonctionne pas, peu importe la taille du nombre, alors ce qui se passe, c'est que votre système dit "Voilà de la mémoire!"mais tant que vous n'essayez pas de l'utiliser, il n'est pas alloué. Auquel cas:

perror();char*p;void*malloc();main(){for(;;){p=malloc(999);if(p)*p=0;else{perror(0);return 0;}}

Devrait faire l'affaire. Si nous pouvons utiliser des extensions GCC, je pense que nous pouvons l'obtenir encore plus petit en changeant char*p;void*malloc();void*p,*malloc(); mais si vous vouliez vraiment jouer au golf, vous seriez sur le code Golf SE.

3
répondu Chris Lutz 2012-02-01 23:23:26
la source

choisissez n'importe quelle plate-forme, bien que l'intégration soit probablement plus facile. malloc (ou new) une tonne de RAM (ou une fuite de RAM au fil du temps ou même le fragmenter en utilisant des algorithmes naïfs). Boom. malloc retour NULL pour moi à l'occasion quand des" mauvaises " choses se produisent.

En réponse à votre montage. Oui, encore. La fragmentation de la mémoire au fil du temps peut faire en sorte que même une allocation unique d'un int peut échouer. Aussi garder à l'esprit que malloc n'est pas seulement allouer 4 octets pour un int, mais pouvez saisir autant d'espace qu'il veut. Il a ses propres trucs de comptabilité et assez souvent va saisir 32-64 octets minimum.

3
répondu Michael Dorgan 2012-02-01 23:24:01
la source

sur un système plus ou moins standard, en utilisant un malloc standard à un paramètre, il y a trois modes de défaillance possibles (que je peux imaginer):

1) Le montant de l'allocation demandée n'est pas autorisé. Par exemple, certains systèmes peuvent ne pas permettre une allocation > 16M, même si plus de stockage est disponible.

2) une zone libre contiguë de la taille demandée, avec limite par défaut, ne peut pas être localisée dans le tas. Il peut encore y avoir beaucoup de mémoire, mais pas suffisamment dans un pièce.

3) le total alloué a dépassé une certaine limite "artificielle". Par exemple, il peut être interdit à l'utilisateur d'allouer plus de 100 M, même s'il y a 200 m libres et disponibles pour le "système" dans un seul tas combiné.

(bien sûr, vous pouvez obtenir des combinaisons de 2 et 3, puisque certains systèmes attribuent des blocs non contigus d'espace d'adresse au tas au fur et à mesure qu'il croît, en plaçant la "limite de taille du tas" sur le total des blocs.)

Notez que certains environnements soutien supplémentaire malloc paramètres tels que l'alignement et l'ID de pool qui peuvent ajouter leurs propres rebondissements.

3
répondu Hot Licks 2012-02-02 00:23:26
la source

Oui. Malloc retournera NULL lorsque le noyau / la lib du système sont certains qu'aucune mémoire ne peut être attribuée.

la raison pour laquelle vous ne voyez généralement pas cela sur les machines modernes est que Malloc n'alloue pas vraiment de mémoire, mais plutôt qu'il demande qu'un "espace d'adresse virtuelle" soit réservé pour votre programme afin que vous puissiez y écrire. Les noyaux tels que Linux moderne over commit, c'est-à-dire qu'ils vous permettent d'allouer plus de mémoire que votre système ne peut fournir (swap + RAM) tant qu'il tous les ajustements dans l'espace d'adresse du système (généralement 48bits sur 64bit plates-formes, IIRC). Ainsi, sur ces systèmes, vous déclencherez probablement un tueur avant de déclencher le retour d'un pointeur nul. Un bon exemple est un 512 Mo de RAM dans une machine 32bit: il est trivial d'écrire un programme C qui sera mangé par le tueur OOM à cause de cela en essayant de malloc tous les RAM + swap disponibles.

(les Overcomitts peuvent être désactivés lors de la compilation sur Linux, donc cela dépend des options de compilation si un noyau Linux de surcharge. Cependant, les périphériques distro stock desktop le font.)

1
répondu user268396 2012-02-01 23:09:43
la source

Autres questions sur