2010-12-03 94 views
0

J'ai un problème étrange avec malloc. J'ai ce typedefs:Comment être sûr que malloc allouera dans une zone différente

typedef struct buffer { 
    int D; 
    int T; 
    unsigned int current_size; 
    unsigned int max_size; 
    pthread_mutex_t mutex; 
    pthread_cond_t non_pieno; 
    pthread_cond_t non_vuoto; 
    msg_t** messages; 

    struct buffer* (*buffer_init)(unsigned int); 
    void (*buffer_destroy)(struct buffer*); 
} buffer_t; 

Et ceci est la fonction buffer_init et buffer_destroy:

buffer_t* buffer_init(unsigned int maxsize) 
{ 
    buffer_t* new_buffer = (buffer_t*)malloc(sizeof(buffer_t)); 
    msg_t** new_messages = (msg_t**)calloc(maxsize, sizeof(msg_t**)); 

    pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; 
    pthread_cond_t np = PTHREAD_COND_INITIALIZER; 
    pthread_cond_t nv = PTHREAD_COND_INITIALIZER; 

    new_buffer->T = 0; 
    new_buffer->D = 0; 
    new_buffer->current_size = 0; 
    new_buffer->max_size = maxsize; 
    new_buffer->messages = new_messages; 
    new_buffer->mutex = mx; 
    new_buffer->non_pieno = np; 
    new_buffer->non_vuoto = nv; 

    new_buffer->buffer_init = buffer_init; 
    new_buffer->buffer_destroy = buffer_destroy; 

    return new_buffer; 
} 

void buffer_destroy(buffer_t* buffer) { 
    pthread_mutex_destroy(&buffer->mutex); 
    free(buffer); 
} 

Si j'imprimer (après chaque appel à la séquence appropriée buffer_destroy de buffer_init) les pointeurs que j'obtiendrai ils sont le plus le même!! Par exemple,

buffer_t* my_buff; 

my_buff = buffer_init(1); 
printf("%d", my_buff); //e.g 10023 
printf("%d", my_buff->mutex); //e.g 56778 

buffer_destroy(my_buff); 
my_buff = buffer_init(1); 
printf("%d", my_buff); //10023 again!!! 
printf("%d", my_buff->mutex); //56778 again!!! 

Je suis certain que les problèmes est que quelque chose va mal avec l'initialisation et désaffectation du buffer_t, connaissez-vous, dans l'ordre:

a) Comment correctement tampon deallocate dans buffer_destroy ? b) Comment initier correctement le mutex? Je veux créer un nouveau mutex à chaque appel! c) Je dois malloc pour D et T? Je dois les libérer ??

Merci pour votre temps! A.

+2

Pourquoi pensez-vous que c'est le problème? Si la mémoire est libérée, elle peut être réutilisée. Essayez d'allouer deux tampons sans les libérer, dans ce cas les adresses doivent être différentes. –

Répondre

6

Cela ne semble pas être un problème! Vous avez alloué de la mémoire, puis l'avez relâchée dans le système. Ensuite, vous avez demandé un peu plus de mémoire de la même taille, et le système malloc a remarqué qu'il y avait de la mémoire disponible de cette taille - la même mémoire que celle que vous aviez auparavant!

Si vous supprimez l'appel à buffer_destroy(), vous devriez voir que vous obtenez des valeurs différentes. (En passant, je recommande d'utiliser "% p" pour imprimer les valeurs du pointeur, plutôt que "% d").

+0

Cela peut sembler ne pas être un problème, mais je soupçonne qu'en raison du PTHREAD_MUTEX_INITIALIZER statique le mutex n'est pas libéré avec buffer_destroy. Comme effet secondaire, j'ai deux tampons différents qui partagent le même mutex, avec un très beau blocage sur la machine Linux et une erreur de segmentation sur mon Mac Os :( –

+2

@Alfredo: On dirait que vous avez beaucoup de malentendus sous-jacents. le même mutex "mais un nouveau mutex à la même adresse.Si quelque chose se référait encore et essayait d'utiliser le vieux mutex après que vous ayez appelé" free ", votre code est cassé.Peut-être que vous devriez expliquer plus de ce qui se passe –

+0

sache (et j'espère) qu'il devrait s'agir d'un nouveau mutex à la même adresse, mais j'ai peur que l'initialisation mutex statique avec PTHREAD_MUTEX_INITIALIZER préserve le mutex à libérer après mon appel à free (buffer): S –

0

Je pense que malloc a une table interne, et lorsque vous libérez de la mémoire (avec free), la "cellule" est juste "busy = 0" alors la mémoire est disponible pour d'autres données. Donc il n'y a pas de problème ici imo.