【问题标题】:Unknown Malloc stack overflow c未知的 Malloc 堆栈溢出 c
【发布时间】:2018-06-24 04:56:44
【问题描述】:

我编写了一段代码,它从文件中获取多个整数(多达 100 000 个整数)作为输入,并将它们存储在“递归”结构中。

只要我在我的电脑上运行这段代码,一切都很好。

代码如下:

typedef struct node{
    int data;
    struct node* next;
} node;

...

node* create(void){
    node* list = (node*)malloc(sizeof(node));
    return list;
}

node* insert(node* list, int temp){
    if(list == NULL){
        list = create();
        list->data = temp;
        list->next = NULL;
        return list;
    }
    list->next = insert(list->next, temp);
    return list;
}

int main(void){
    ...
    node* list = NULL;
    while(there is still data to input){
        list = insert(list, data);
    }
}

但是,当我尝试在我的 Android 手机上运行此代码时,我得到了一个

malloc 堆栈溢出错误

(我知道手机上保留的堆栈空间比 PC 上的要少)。

问题是,据我所知,这个程序应该使用大量的堆栈内存。

这就是我认为在我的程序中发生的事情(如果我错了,请纠正我):

1)。 node* list = NULL ==> 在堆栈上分配了一个指针(8 字节)的空间;

2)。 list = insert(list, temp) ==> 转到数据流的末尾。

3)。 list = create() ==> create() 函数被调用;

4)。 node* list = (node*)malloc(sizeof(node)) ==> 指针空间分配在堆栈上(8 字节),结构空间分配在堆上(16 字节);

5)。 return list ==> create() 函数已关闭,因此堆栈上的变量 node* list 被“释放”,而堆上分配的空间仍然存在。

所以我的程序应该使用大量堆内存,但只有 8 字节的堆栈内存(main ==> node* list = NULL 中的第一个指针所需的内存),我怎么可能得到错误:

malloc 堆栈溢出

?

谢谢

洛伦佐

附:对不起,伙计们,但我试图让我的代码更短,但我写的东西毫无意义。我现在修好了(或者我希望如此)。

【问题讨论】:

  • list->next = NULL; list = list->next; 在我看来不是很好
  • 只要我在我的电脑上运行这段代码,一切都很好。 - 鉴于上述情况,我真的怀疑它。
  • 您的代码可能会调用未定义的行为(请参阅上面的 upvoted cmets)。因此它可能在一个平台上运行良好,而在另一个平台上崩溃。
  • 我的猜测是你过度强调堆分配器并且内部使用的任何算法都在使用整个堆栈。
  • 什么是“malloc 堆栈溢出错误”?吐出该文本的任何工具都是垃圾,不应该使用。

标签: c pointers stack malloc stack-overflow


【解决方案1】:

你过度使用了变量列表。

您需要保留当前节点的指针,而不是用以下行覆盖它:

list = create();

考虑以下或类似的:

int main(void){
    ...
    node* list = NULL;
    node* current = NULL;
    node* next = NULL;
    while(...){
        ...
        next = create();
        if(list == NULL)   //list empty case
        {
            list = next;
            current = next;
        }
        current->next = next;
        next->next = NULL;
        current = next;
    }
}

我鼓励您将其中的一些逻辑封装在一个与 main() 分开的函数中。

分段错误的实际原因不在您显示的代码中,而是在您当前的代码中,当您每次尝试使用 list 时,它都是 NULL,这可能是您未定义的行为。

【讨论】:

  • 对不起,你是对的。我试图过度简化我的代码以使其更易于阅读,并且我写了一些毫无意义的东西。我已经用我的原始代码更新了我的代码(它实际上具有您正在谈论的功能)。
  • 我同意你在这里所说的一切。但是,“malloc 堆栈溢出”不是分段违规,或者至少不是由于堆空间不足而取消引用空指针所期望的错误。无论如何,您的代码允许最终回收内存这一事实可能并不能缓解问题。
猜你喜欢
  • 2012-12-20
  • 2011-03-02
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
相关资源
最近更新 更多