web-dev-qa-db-fra.com

Comment libérer de la mémoire en C?

J'écris du code qui a beaucoup de tableaux 1 et 2 dimensions. J'ai "erreur: impossible d'allouer la région" et je pense que c'est parce que trop de mémoire est allouée. J'utilise les fonctions "malloc" et "free", mais je ne suis pas sûr de les utiliser correctement. Peut-être savez-vous où je pourrais voir de bons exemples sur la gestion de la mémoire en C?

donc .. J'essaye juste de faire fonctionner un algorithme et pour l'instant ce code est fonction après fonction ..

//memory allocation for 1D arrays
buffer = malloc(num_items*sizeof(double));

//memory allocation for 2D arrays
double **cross_norm=(double**)malloc(150 * sizeof(double *));
for(i=0; i<150;i++)
    {
        cross_norm[i]=(double*)malloc(num_items*sizeof(double));
    }

    //code
Window(N, window_buffer);
STFTforBMP(buffer,N,f, window_buffer);
getMagnitude(buffer,f, N, magnitude);
calculateEnergy(flux,magnitude, f);
calculateExpectedEnergy(expected_flux, candidate_beat_period, downbeat_location, f);
calculateCrossCorrelation(cross, flux, expected_values, f);
findLargestCrossCorrelation(&cross_max, cross, f);
normalizeCrossCorrelation(cross_norm, &cross_max, cross, f);
    ...............

Comment dois-je utiliser la fonction free?

32
andrey

Vous devez free() la mémoire allouée dans l'ordre inverse exact de la façon dont elle a été allouée à l'aide de malloc().

Notez que vous ne devez libérer la mémoire qu'après avoir fini d'utiliser les pointeurs alloués.

allocation de mémoire pour les baies 1D:

    buffer = malloc(num_items*sizeof(double));

désallocation de mémoire pour les tableaux 1D:

    free(buffer);

allocation de mémoire pour les tableaux 2D:

    double **cross_norm=(double**)malloc(150 * sizeof(double *));
    for(i=0; i<150;i++)
    {
        cross_norm[i]=(double*)malloc(num_items*sizeof(double));
    }

désallocation de mémoire pour les tableaux 2D:

    for(i=0; i<150;i++)
    {
        free(cross_norm[i]);
    }

    free(cross_norm);
42
Alok Save

En fait, vous ne pouvez pas "libérer" la mémoire manuellement en C, dans le sens où la mémoire est libérée du processus vers le système d'exploitation ... lorsque vous appelez malloc(), le libc-runtime sous-jacent demandera à l'OS une région de mémoire. Sous Linux, cela peut être fait via un appel relativement "lourd" comme mmap(). Une fois que cette région de mémoire est mappée à votre programme, il existe une configuration de liste liée appelée la "mémoire gratuite" qui gère cette région de mémoire allouée. Lorsque vous appelez malloc(), il recherche rapidement dans le free-store un bloc de mémoire libre à la taille demandée. Il ajuste ensuite la liste liée pour refléter le fait qu'un morceau de mémoire a été retiré du pool de mémoire alloué à l'origine. Lorsque vous appelez free(), le bloc de mémoire est replacé dans la librairie en tant que nœud de liste liée qui indique qu'il s'agit d'un bloc de mémoire disponible.

Si vous demandez plus de mémoire que ce qui se trouve dans le free-store, le libc-runtime demandera à nouveau plus de mémoire du système d'exploitation jusqu'à la limite de la capacité du système d'exploitation à allouer de la mémoire pour les processus en cours d'exécution. Cependant, lorsque vous libérez de la mémoire, elle n'est pas renvoyée au système d'exploitation ... elle est généralement recyclée dans le magasin gratuit où elle peut être réutilisée par un autre appel à malloc(). Ainsi, si vous faites beaucoup d'appels à malloc() et free() avec des demandes de taille de mémoire variables, cela pourrait, en théorie, provoquer une condition appelée "fragmentation de la mémoire", où il y a suffisamment espace dans le free-store pour allouer votre bloc de mémoire demandé, mais pas assez contig espace pour la taille du bloc que vous avez demandé. Ainsi, l'appel à malloc() échoue, et vous êtes effectivement "en manque de mémoire" même s'il peut y avoir beaucoup de mémoire disponible en tant que quantité totale d'octets dans le magasin gratuit.

28
Jason