宣言和分配

时间:2014-07-26 01:35:55

标签: c linux realloc alloc

我对C分配有些怀疑。

#include <stdlib.h>

typedef struct MyStruct {
    char CharsInMyStruct[50];
} MyStruct;

int main(void) {

    struct MyStruct * s;

    s = malloc(100 * sizeof *s);
}

我被告知分配是“智能的”,因为在我使用内存之前,空间不是“真正”(物理上)分配的。一旦我使用MyStruct的第一个元素或者在使用每个元素时分配内存,是否物理分配了内存?

我认为如果我需要动态读取文件并复制动态结构中的每一行,我可以只分配100个元素,然后在读取文件后重新分配正确的维度,所以我不必阅读两次以前知道为每行分配或重新分配多少。这可能/允许吗?这是一个很好的解决方案吗?

编辑:对不起,我太在意理论,我忘了添加一个不错的代码。也许问题不够明确,但我不需要知道如何编码我正在考虑的内容;我只需要知道如何分配内存。

4 个答案:

答案 0 :(得分:3)

原则上,调用malloc()会立即分配请求的内存。如果它无法执行此操作,malloc()调用将返回一个空指针,让调用者知道。

实际上,虽然某些系统(包括Linux)使用&#34;延迟分配&#34;。 malloc()调用会立即分配一系列内存地址,但不一定要立即分配实际内存页面。当您的程序稍后访问&#34;已分配的&#34;内存,物理内存由内核分配。我们的想法是避免分配可能永远不会被使用的内存,特别是在fork进程时(子进程继承其父进程的副本,但在使用之前通常是exec()另一个可执行文件它)。

这种方法的一个主要缺点是,如果在尝试使用内存时 ,则无法报告失败。当系统内存不足时,"OOM killer"可能会开始终止进程​​ - 不一定是执行分配的进程。

有人认为这种行为会导致Linux上的C实现不一致。

我对非Linux系统不熟悉。

但是,对于大多数实际用途,只要您不分配巨大的内存量,您就可以忽略所有这些。您应该始终通过返回空指针来检查malloc()是否报告失败,并采取一些操作(即使您只是终止程序)。如果你在一个无限循环中做一个大的malloc,很可能会发生坏事。但是当资源由于某种原因而供不应求时,程序可能会开始崩溃。你最好的防御是设计你的程序,这样如果它意外终止,它就不会让事情处于不一致的状态。

答案 1 :(得分:1)

评论说:

struct myStruct * structLink;
structLink = malloc (sizeof(struct myStruct));

完成后:

free(structLink);

解除分配。

答案 2 :(得分:1)

正如其他人所说,逻辑上malloc()分配空间并且可以立即使用。正如Keith Thompson中提到的那样answer,Linux采用懒惰的内存分配方式,所以你可以(如果你运气不好)分配空间,检查它是否已经分配,​​但是之后仍然会崩溃,因为记忆力毕竟不可用。

  1. 是的,分配100个条目是合法的,从文件中读取以填充其中一些条目,然后realloc()将数组缩小到所需大小(如果后面的条目少于100个)所有

  2. 您还可以分配一个条目数组(比如说2个条目开始),realloc()空间可以根据需要添加更多条目。但是,为了避免二次行为(将旧空间复制到新空间),标准建议是每次realloc()时将条目数加倍。如果你担心过度分配,你总是可以在循环后应用缩小的realloc()。使用较小的值开始,以便realloc()代码得到锻炼(测试,调试)。

答案 3 :(得分:1)

我想你可能对内存使用的想法有误。当你分配内存时,内存总是在那里开始,malloc只是告诉计算机为你预留这么多空间。在您完成后使用free()时,您释放的指针仍将指向该地址。唯一的区别是程序会知道它不再是你的使用空间了。 (虽然在你遇到段故障之前,C可能仍会允许你)

至于你的第二段,你的方式取决于实施。虽然我真的不明白为什么每次你在新文件中阅读时都不能只是马戏团。

请原谅,如果这不是您正在寻找的东西。