C语言 调用malloc()而不调用free()的真正后果是什么?它能让程序发疯吗,比如永远循环



我现在的程序有一个大问题。在on循环中,两个函数如果我在这个循环中再调用一个函数,就会得到一个永久循环!即使是printf("bah");也会产生永久循环

给出正常的执行。

//size = 10 (example)
while(size > 0) {
  a(); // decrement by 2
  b(); // decrement by 2
}

,

//size = 10 (example)
while(size > 0) {
a(); // decrement by 2
b(); // decrement by 2
putchar(' ');
}

给出一个永久循环。唯一不同的是putchar()调用。

很难假设一些事情,但是对正在发生的事情有一些想法吗?

a() and b() '函数的基本功能是:

从数组中获得两个结构体,size减去1printf()中的一些成员。这样的结构(目前)只在程序结束时才释放。

我发布这部分代码是为了了解(可能)发生了什么。这部分代码的所有代码都非常大(要贴在这里供我们阅读)。

编辑:

以下是a()b()的最小实现:

void a(void) {
  foo_t* f = top;
  while(f->y == STATE_X) {
  get(&a); get(&b); /* it's equivalent to pop() in a linked list. size is size=size-1 in each get call() */
  printf("%d,%dn",a->x,ab->x);
  f = f->next;
 }
 top = f;
}
void a(void) {
  foo_t* f = top;
  while(f->y == STATE_Y) {
  get(&a); get(&b); /* it's equivalent to pop() in a linked list. size is size=size-1 in each get call() */
  printf("%d,%dn",a->x,ab->x);
  f = f->next;
 }
 top = f;
}

get() -在我的上下文中相当于pop()

top -指向最后一个从堆栈中处理的struct footype

size -当前栈上元素的计数。

struct footype也是这样实现的,有一个prevnext指向它的前一个和下一个成员。

如果我们完全按照你所说的代码去做——内存被分配了,但从未释放——那么内存将一直被分配,直到程序结束。如果你继续分配更多的内存而不释放,最终你会用完的…此时malloc可能开始失败并返回空指针。(当然,如果我们按照C标准,尝试通过空指针访问内存可能会导致各种奇怪的事情随之而来。但是,在Linux中最常见的结果是段错误。

然而,如果没有ulimit设置,您可能也会用完所有的交换空间,这可能会导致最终的巨大减速。当然,在你的进程中使用所有的内存,会从其他进程中占用内存。最终,可能会发生以下两种情况之一:

  • 其他进程可能开始分配内存失败…如果他们没有考虑到这一点,他们可能会崩溃。

  • Linux会有意地分发虚拟内存——基本上,既不支持RAM也不支持交换空间的内存页。(这样做的原因有点复杂,但在上下文中是有意义的。)只有当一个进程试图实际使用内存时,内核才会为它清理一些RAM。如果没有可用的RAM和空间可以交换,内核将杀死一个现有的进程来回收它的虚拟内存。

    (如果到这个程度,就会有一个算法来决定杀死哪个进程。它通常会选择内存占用最严重的进程——在这种情况下,可能是您的进程。

不过,这就是破坏的程度。你会减慢进程的速度,扰乱其他进程,并可能导致其中一个进程被杀死(很可能是你的进程)。

有一件事它不会做,至少它自己不会做,那就是让循环永远继续下去。为了引起这种情况,程序必须(1)检查失败,(2)永远循环重试失败的操作直到成功,而不改变与操作相关的任何内容。

最新更新