【问题标题】:C programming: SIGABRT 134 error; am I freeing this memory correctly?C 编程:SIGABRT 134 错误;我是否正确释放了这个内存?
【发布时间】:2018-02-14 16:31:34
【问题描述】:

我有一个这样的嵌套数据结构(这些是初始化):

Interval *newInterval(int b, int e, int m){
    static Interval i;
    i.b = b;
    i.e = e;
    i.m = m;
    return &i;
}
Signal *newSignal(int size){
    static Signal s;
    s.intervals = malloc(size * sizeof(Interval));
    s.top = 0;
    s.size = size;
    return &s;
}

Stack *newStack(int size){
    static Stack st;
    st.signals = malloc(size * sizeof(Signal));
    st.top = 0;
    st.size = size;
    return &st;
}

数据的结构方式: 多个 Interval 结构指针存储在每个 Signal 结构的 'intervals' 数组中。每个 Signal 结构指针都存储在 Stack 结构的“信号”数组中(总是只有一个)。

        -> [Signal 0] -> [Interval 0][Interval 1][Interval 2]...
[Stack] -> [Signal 1] -> [Interval 0][Interval 1]
        -> [Signal 2] -> [Interval 0][Interval 1][Interval 2]...

我如何尝试访问和释放数据:我有两个函数可以从结构中打印出数据,并尝试释放使用 malloc(和 realloc)分配的内存。但是我似乎得到了一个 SIGABRT(错误 134)。我想这是因为我如何释放内存;但我不知道该怎么办!

    void pop(Signal *s, int n){
    if(n < s->top) {
        printf("[%d,%d)@%d ", s->intervals[n].b, s->intervals[n].e, s->intervals[n].m);
        pop(s,n+1);
    }
    else {
        free(s->intervals);
    }
}

void printIntervals(Stack *st){
    for(int i=0; i<st->top; i++){
        pop(&(st->signals[i]), 0);
        printf("\n");
        free(&(st->signals[i]));
    }
}

1. printIntervals 被调用一次,然后依次为每个信号调用 pop 函数。

2. pop函数递归打印出每个区间结构体,直到包含区间的数组为空,此时我 尝试从信号中释放区间数组。

3. 此时弹出结束,流程返回到 printIntervals。在这里,我尝试释放信号数组,因为有 没有什么可打印的了,循环继续打印下一个信号 来自堆栈。

我释放内存的方式不正确吗?如何修复内存错误?谢谢。

【问题讨论】:

  • static Stack st; 后跟st.signals = malloc() 很糟糕,很容易出现内存泄漏。请准备好并在您使用它的上下文中理解static 的含义。看来您想避免malloc()ing,为此您做了非常非常错误的事情。

标签: c pointers memory struct free


【解决方案1】:

如果你 free() 多个 Stack 指针——以一个为例——你实际上总是在释放同一个指针。

当您在函数范围内将结构声明为 static 时,它只初始化一次,后续调用将影响您最初返回的指针,因此在一个成员上使用 malloc() 有效地使您的所有指针指向同一个 @ 987654325@ed 区。所以它指向的前一个指针现在丢失了,你不能释放它。

此外,您不能 free() malloc() 未返回的内容。特别是在实际上是评估运算符的&amp; 地址的结果的指针上调用free() 是可疑的并且可能是错误的。

您的代码可能应该固定如下,

Interval *
newInterval(int b, int e, int m)
{
    Interval *interval;
    interval = malloc(sizeof(*interval));
    if (interval == NULL)
        return NULL;
    interval->b = b;
    interval->e = e;
    interval->m = m;
    return interval;
}

Signal *
newSignal(int size)
{
    Signal *signal;
    signal = malloc(sizeof(*signal));
    if (signal == NULL)
        return NULL;
    signal->intervals = malloc(size * sizeof(*signal->intervals));
    if (signal->intervals == NULL) {
        free(signal);
        return NULL;
    }
    signal->top = 0;
    signal->size = size;
    return signal;
}

Stack *
newStack(int size)
{
    Stack *stack;
    stack = malloc(sizeof(*stack));
    if (stack == NULL)
        return NULL;
    stack->signals = malloc(size * sizeof(*stack->signals));
    if (stack->signals == NULL) {
        free(stack);
        return NULL;
    }
    stack->top = 0;
    stack->size = size;
    return stack;
}

此外,良好的设计也很重要,一个名为 print* 的函数根本不会释放任何东西,事实上,您应该避免在给定上下文中释放分配在不同上下文中的内存。

【讨论】:

  • 回复。声明“特别是在实际上是评估运算符的 & 地址的结果的指针上调用 free() 是明显错误的。”:例如,char *p = malloc(10); free(&amp;p[0]); 可以正常工作。重要的不是地址,而是它是否产生正确的指针。
猜你喜欢
  • 2015-06-18
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-23
  • 1970-01-01
相关资源
最近更新 更多