在我的堆栈构建期间,我遇到了在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];
}
答案 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的自动分配复制到返回值更安全。无论如何。