循环中的Malloc,所有分配的块是否连续?

3

我有一个函数,在其中使用了本地数组。我想返回指向它的指针,但是如果不手动分配内存,这是不可能的。因此我想知道是否可以像这样进行内存分配:

for(i = 0; i < 26; i++)
{
    llist[i] = malloc(sizeof(SomeStruct));
}

可以这样稍后释放:
// (where ptr is a pointer to the first allocation in llist)

for(i = 0; i < 26, i++)
{
    free(ptr);
    ptr += sizeof(SomeStruct);
}

编辑:

看起来我不能这样做。如果只有指向第一个元素的指针,是否有任何方式可以释放所有内存?或者我应该采取完全不同的方法?


2
你不能只在循环外部执行malloc(sizeof(SomeStruct))*26 吗? - K-ballo
@K-ballo 只是为了明确,我想做的是 malloc(sizeof(SomeStruct) * 26); 还是 malloc(sizeof(SomeStruct)) * 26; - providence
当然应该是 malloc(sizeof(SomeStruct) * 26),我的错。 - K-ballo
3个回答

5

不行,它不能这么做。这些块没有保证是连续分配的。事实上,在我所见过的现代实现中,它们几乎肯定不连续。大多数存储块的大小,并且通常在每个块之前立即存储其他信息。此外,如果内存碎片化,块可能会出现在其他数据之间的空闲空间中的任何位置,其中没有足够的空间将它们放置成连续的块。


该死。如果只有第一个元素的指针,是否有办法稍后释放所有块? - providence
如果我这样做 llist = malloc(sizeof(SomeStruct) * 26); 那么 llist 指向的是整个内存块,而不是第一个项目,对吗? - providence
是的。那么你将把llist变成一个SomeStruct*并像现在一样使用[]访问它,除了不需要额外的解引用,所以它将是llist[i].member而不是llist[i]->member - Dark Falcon
啊,有趣。我不知道你可以这样做(对C语言新手来说)。谢谢你的提示。 - providence

2
不可以。在第一个空的位置,malloc 只能容纳一个结构体。如果这种情况发生了,下一个块会被放在其他地方。

0

这取决于您在循环内部执行的操作。有些函数会在内部分配缓冲区,这意味着可能会在您不知情的情况下调用malloc()。在简单的循环中,值应该是连续的。此外,一旦引入多线程,所有的打赌都将作废,因为另一个线程中的某些内容也可以malloc()内存。

实际分配的位置还取决于您的内存有多么碎片化。可能没有足够的连续块来处理您的请求,因此实际分配可以来自空闲空间中的任何位置。


在很少的实现中,这些不会是连续的。即使在发布版本中,堆通常也会在每个分配之间跟踪分配大小。 - Mooing Duck
你应该将“SHOULD”更改为“could”或“might”。 malloc()不能保证给定块的分配位置,因此您不应该依赖顺序分配的块按顺序进行定位。 - Caleb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接