【问题标题】:How to be sure malloc will alloc in a different area如何确保 malloc 将分配到不同的区域
【发布时间】:2010-12-03 16:22:53
【问题描述】:

我对 malloc 有一个奇怪的问题。我有这个类型定义:

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;

这是 buffer_init 和 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);
}

如果我打印(在每次调用正确的 buffer_destroy buffer_init 序列之后)我获得的指针是最相同的!! 例如

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!!!

我很确定问题是buffer_t的初始化和释放出了问题,你知道吗,按顺序:

a) 如何正确地将缓冲区释放到 buffer_destroy? b)如何正确初始化互斥锁?我想在每次调用时创建一个新的互斥锁! c)我必须为 D 和 T 分配 malloc 吗?我必须释放它们??

感谢您的宝贵时间! A.

【问题讨论】:

  • 您为什么认为这是问题所在?如果内存被释放,它可以被重用。尝试分配两个缓冲区而不释放它们,在这种情况下地址必须不同。

标签: c pointers malloc free


【解决方案1】:

这看起来不是问题!您已经分配了一些内存,然后将其释放回系统。然后你请求了更多相同大小的内存,malloc 系统注意到有一些可用的内存大小相同 - 与它之前给你的内存相同!

如果您删除对buffer_destroy() 的调用,您应该会看到您得到不同的值。 (顺便说一下,我建议使用“%p”来打印指针值,而不是“%d”)。

【讨论】:

  • 这似乎不是问题,但我怀疑由于静态 PTHREAD_MUTEX_INITIALIZER 互斥体没有被 buffer_destroy 释放。作为副作用,我有两个不同的缓冲区共享同一个互斥锁,在 linux 机器上有一个漂亮的死锁,在我的 Mac OS 上有一个分段错误:(
  • @Alfredo:看起来你有很多潜在的误解。它不是“相同的互斥锁”,而是位于同一地址的新互斥锁。如果在您调用 free 后仍有任何内容引用并尝试使用旧互斥锁,则您的代码已损坏。也许你应该解释更多发生的事情。
  • 我知道(并且我希望)它应该是同一地址的新互斥锁,但我担心使用 PTHREAD_MUTEX_INITIALIZER 的静态互斥锁初始化会在我调用 free 后保留要释放的互斥锁(缓冲区):S
  • @Alfredo Di Napoli:恐怕我不得不同意@R。 - 在 Linux 上,我很确定,因为我非常了解代码,使用 PTHREAD_MUTEX_INITIALIZER 在同一地址重新初始化互斥锁将完全重新初始化互斥锁,不会留下以前在同一地址的任何痕迹,假设当时没有其他线程在互斥体上等待。正如 R. 所说,如果另一个线程在您释放互斥锁时正在使用它,那么 that 是您需要解决的问题,而不是新互斥锁在同一个地方重新分配的事实:-)
  • 虽然在 linux 上不太可能出现问题,但 PTHREAD_MUTEX_INITIALIZER 仅用于静态初始化器。 (即,具有静态对象生命周期的互斥锁)。您不应该将它用于局部变量,然后复制该 mutex ,使用 = 运算符复制互斥锁是 posix 未定义的。使用 pthread_mutex_init()
【解决方案2】:

我认为 malloc 有一个内部表,当你释放内存(有空闲)时,“单元”只是设置为“busy = 0”,然后内存可用于其他数据。 所以这里没有问题。

【讨论】:

    猜你喜欢
    • 2012-12-10
    • 2021-02-04
    • 2017-04-07
    • 1970-01-01
    • 2017-03-05
    • 2021-02-08
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    相关资源
    最近更新 更多