0

我目前的程序有一个大问题。在循环内部,如果我在此循环中执行另一个函数调用,则有两个函数,我得到一个永远循环!甚至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() andb()` 函数的作用基本上是:

从一个数组中获取两个结构,递减一个size及其1一些printf()成员。此类结构仅在程序结束时才被释放(尚未)。

我将这部分代码发布到 tro 以了解(可能)发生了什么。这部分代码中的所有代码都非常大(发布在这里供我们阅读)。

编辑:

这是一个最小的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,%d\n",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,%d\n",a->x,ab->x);
  f = f->next;
 }
 top = f;
}

get()pop()-在我的上下文中是我的等价物。

top - 指向最后struct footype从堆栈处理的。

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

struct footype也被实现为与 this 关联,有一个prevandnext指向它的前一个和下一个成员。

4

1 回答 1

5

如果我们纯粹按照您所说的关于未显示的代码——内存已分配,但从未释放——那么该内存将保持分配状态,直到程序结束。如果您继续分配更多内存而不释放任何内存,最终您将用完......此时malloc可能会开始失败并返回空指针。(当然,如果我们按照 C 标准,尝试通过空指针访问内存可能会导致各种奇怪的事情发生。不过,Linux 中最常见的结果是段错误。)

但是,如果没有ulimit设置,您可能也会用完所有交换空间,这可能会导致最终速度大幅下降。当然,在你的进程中使用所有的内存,就会把它从其他进程中拿走。最终,可能会发生以下两种情况之一:

  • 其他进程可能开始无法分配内存......如果他们没有考虑到这一点,他们可能会中断。

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

    (如果它走得那么远,有一个算法可以决定要杀死哪个进程。它通常会更喜欢记忆最严重的进程 - 在这种情况下,它可能是你的。)

不过,这与损坏的程度有关。你会减慢速度,并与其他进程混淆,并可能导致其中一个进程被杀死(可能是你的进程)。

它至少不会做的一件事是导致循环永远持续下去。为了让它发生这种情况,程序必须(1)检查失败,(2)循环永远重试失败的操作直到它成功,而不改变与操作相关的任何东西。

这里正在发生其他事情。

于 2013-05-20T22:12:45.603 回答