联盟如何防止内存碎片?

时间:2016-09-03 13:48:30

标签: c memory

我正在浏览这个link并在页面上学习C.有趣的部分:

  

工会的真正目的是通过为内存中的数据安排标准大小来防止内存碎片。通过具有标准数据大小,我们可以保证在释放动态分配的内存时留下的任何漏洞将始终可由同一类型的并集的另一个实例重用。

我通过以下代码理解这一部分:

typedef struct{
    char name[100];
    int age;
    int rollno;
  }student;

typedef union{
     student *studentPtr;
     char *text;
  }typeUnion;

int 
main(int argc, char **argv)
{
  typeUnion union1;

  //use union1.studentPtr

  union1.text="Welcome to StackOverflow";
  //use union1.text

  return 0;
}

好吧,在上面的代码中,union1.text正在重用union1.studentPtr以前使用的空间,而不是完全但仍在使用。

现在,我不理解的部分是,何时释放malloc的空闲空间不能导致内存碎片化?

修改:通过评论和回答,必须使用the classic text,将此修改添加到帖子中,假设它会对像我这样的初学者有所帮助

2 个答案:

答案 0 :(得分:1)

这些评论在unions方面具有更多专业知识。

关于你的具体问题,这是我的理解:

  • union为union变量中的最大数据类型留出内存。例如,在联合中使用short intlong int会为long int 2 bytes set aside for long int

  • 留出足够的内存
  • 想象一下,您宣布short int变量而不是联合。1 byte for small int 但是需要使用long int。因此,您在free freeing small int memory上使用short int 然后使用malloclong int分配内存。这必须是精力充沛的记忆。所以现在你的记忆就像这样。 enter image description here在其他已使用的内存块中间有一个空闲字节。坐在那里等着你特别请求1字节的内存。

旁白:如果您正在学习c,我建议the classic text。它已过时但我喜欢简洁,清晰和文本书风格的方法。

答案 1 :(得分:0)

该页面错误,大多数程序只是假设内存使用情况良好而且没有注意它。

在下图中,假设每个字符代表8个字节。字母代表不同的分配,下划线代表空闲内存。涉及的规模很小,我跳过细节(比如大多数malloc实现使用的分配元数据),但原则应该在那里。

从空记忆开始

_____________________________________________________

然后在程序运行时发生一堆32字节的分配。

AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLL________

程序分配的内存一直延伸到' L'的最后一个字节。分配时,它使用12 * 8 * 4 = 384字节。

现在该程序释放了所有其他分配。

AAAA____CCCC____EEEE____GGGG____IIII____KKKK__________

现在程序实际上只使用6 * 4 * 8 = 192个字节,但操作系统必须保留所有352个字节,而不是第一个' A'到最后' K'分配给该计划。在所有分配之间释放的空白是内存碎片的一个例子。

现在程序想要分配另一个32字节的块。可能会发生这样的事情:

AAAAMMMMCCCC____EEEE____GGGG____IIII____KKKK_________

新的分配适合由frees创建的一个空白,这很好,因为它回收了其中一个空白,因此我们浪费的空间更少。

现在说程序需要分配一个40字节的块。没有差距足够大,因此分配必须在最后进行,操作系统必须为程序分配更多内存,352 + 40 = 392字节。这些空白中的所有记忆都被浪费了。这是由于网页所讨论的内存碎片造成的浪费。

如果所有分配都是40字节开始,那么间隙回收可以最大化。