• # Pour moi: pré-allouer un buffer d'urgence (a l'ancienne)

    Posté par . En réponse au journal Gestion des erreurs d’allocation mémoire en C. Évalué à 5. Dernière modification le 27 octobre 2016 à 19:26.

    La réponse dépend vraiment de ce que fait ton programme. Dans mon cas, j'ai ma surcouche à malloc()/free()/realloc(), et lors de l'init de mon programme je reserve un bloc de 1Mo. Si un malloc() échoue, je tappe dans mon bloc de 1Mo et je met une variable globale à TRUE disant qu'il n'y a plus de mémoire. Comme mon programme fait une grosse boucle, je consulte souvent cette variable et si elle est activée je libère de la mémoire utilisée pour faire du cache. Si on échoue trop souvent, on loggue proprement l'erreur et on quitte.

    Franchement, je ne trouve pas que wrapper malloc soit trop lourd. C'est pénible à court terme, c'est pratique de pouvoir factoriser cette fonction critique à long terme. De manière générale, je wrappe toutes les fonctions externes tant que possible, ça aide pour la portabilité.

    Je ne recommande pas de faire un bzero() sur ton buffer alloué. Tu y perds énormément en performance si tu programme fait beaucoup d'allocations.

    La plupart des bibliothèques (des bonnes en tout cas) te permettent de définir quelles fonctions utiliser pour malloc()/realloc()/free(), donc c'est globalement pas un problème (sauf pour la libc).

    CECI ETANT DIT:

    • Comme tu le dis, sous Linux, un malloc() qui réussit n'indique pas forcément qu'il y a de la mémoire dispo. /proc/sys/vm/overcommit_memory peut t'aider mais risque de dégrader les perfs.

    • Les problèmes de fragmentation de mémoire font que si tu libères 200 blocs de 1ko, tu ne sais pas si ton allocation suivante de 200ko va fonctionner (probablement pas) ;

    • Si tu gères des énormes buffers, rien de tout ceci ne s'applique;

    J'avais lu un papier récemment qui disait quand quand l'allocation de mémoire échoue, tu es fichu de toute façon. C'est pas forcément faux. Peut être que faire un abort() propre (avec message d'erreur) dans ton malloc() custom est une approche plus simple (je l'ai fait pendant longtemps).

    (Ref: La première fois que j'ai vu cette histoire de buffer pré-alloué c'était dans 'Inside Macintosh' pour programmer sous système 7).