C - 释放堆栈内数组内的特定结构

时间:2018-03-07 18:06:13

标签: c arrays struct stack free

在我的堆栈构建期间,我遇到了在Pop函数中释放数组内元素的问题。 这是代码:

Element Pop(Stack *stackPtr)
{
    Element temp = stackPtr->content[stackPtr->size-1];
    Element* newE = (Element*)realloc(stackPtr->content,(stackPtr->size-1)*sizeof(Element));

    free(stackPtr->content[stackPtr->size-1]);

    stackPtr->content=newE;
    stackPtr->size--;
    return temp;
}

由于某种原因,free(stackPtr->content[stackPtr->size-1]);每次都会出错。 为什么这样,我该如何解决? 感谢。

这是整个代码:

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>

typedef struct 
{
    int kind; // boolean
    int num;
    char ch;
} Element;

typedef struct 
{
    Element *content;
    int size;
} Stack;

void Init(Stack* stackPtr)
{
    stackPtr->content = (Element*)malloc(1*sizeof(Element));
    stackPtr->content[0].kind = 3;
    stackPtr->content[0].ch = 'a';
    stackPtr->content[0].num = -2;
    stackPtr->size = 1;
}

void Push(Stack* stackPtr, Element element)
{
    stackPtr->content = (Element*)realloc(stackPtr->content,((stackPtr->size)+1)*sizeof(Element));
    stackPtr->size++;
    stackPtr->content[stackPtr->size-1] = element;
}

Element Pop(Stack *stackPtr)
{
    Element temp = stackPtr->content[stackPtr->size-1];
    Element* newE = (Element*)realloc(stackPtr->content,(stackPtr->size-1)*sizeof(Element*));

    free(stackPtr->content[stackPtr->size-1]);

    stackPtr->content=newE;
    stackPtr->size--;
    return temp;
}

Element Top(Stack *stackPtr)
{
    return stackPtr->content[stackPtr->size-1];
}

2 个答案:

答案 0 :(得分:0)

当然这会崩溃 - 你刚刚重新分配了stackPtr->content所指向的数据,所以数组访问现在无效。

由于您已经重新分配,并且您要返回已删除的元素,因此对free的调用毫无意义,并且在多种方面都是非法的。记忆已经是免费的,但不仅如此,它从来都不是一个开头的指针。

还要注意realloc的哪些参数有效。如果您的Pop功能&#34;删除&#34;最后一个元素,你会尝试重新分配到零大小,这是不合法的。

无论如何你应该进行防御性检查,确保没有人试图从已经空的筹码中弹出。

答案 1 :(得分:-1)

由于content []是一个指针数组,realloc应该使用sizeof(Element *),而不是sizeof(Element),特别是如果sizeof(Element)小于sizeof(*)。 编辑以反映评论的意图:

Element *Pop(Stack *stackPtr)
{
if (stackPtr->size==0) return NULL;
Element temp = stackPtr->content[stackPtr->size-1];
stackPtr->size--;
if (stackPtr->size==0) free(stackPtr->content)
else {   
Element* newE = (Element*)realloc(stackPtr->content,stackPtr->size)*sizeof(Element));
stackPtr->content=newE;
}
Element* rslt = malloc(sizeof(Element);
memcpy(rslt,&temp,sizeof(Element));
return rslt;
}

在使用代码中,返回的指针需要单独释放。我认为这比假设编译器将temp的自动分配复制到返回值更安全。无论如何。