链栈的两个问题

一、问题

1、pHeader为什么不声明为指针类型?

struct LStack {
    struct stackNode pHeader;  //不用指针类型,因为内存在malloc时已经给它分配好了
    int m_Size;
};

如果我们将pHeader声明为struct stackNode*类型,那么在使用链栈时,我们需要额外进行内存的分配和释放操作。每次插入或删除元素时,需要创建新的节点并将指针赋值给pHeader->next,或者释放已经存在的节点。这样会增加复杂性和内存管理的负担。

而将pHeader声明为struct stackNode类型,可以直接将节点作为值存储在pHeader中,不需要进行额外的内存分配和释放操作。这样简化了代码逻辑,并且节省了额外的内存开销。

2.不能重复释放内存空间

重复释放内存可能会导致以下问题:

  1. 访问非法内存:重复释放后,如果你尝试访问已经释放的内存,那么程序将会访问非法内存,这可能导致崩溃或者其他未定义的行为。

  2. 内存泄漏:如果重复释放了相同的内存块,那么这部分内存将无法被其他程序使用,造成内存泄漏的问题。

  3. 程序崩溃:重复释放内存可能会破坏内存管理的数据结构,从而导致程序崩溃或者产生其他无法预料的错误。

因此,为了避免这些问题,我们需要确保在释放内存之前,确认该内存块确实需要释放,并且只释放一次。同时,需要避免在释放后继续访问已经释放的内存。

在你的代码中,如果重复调用destroy_LinkStack函数,就会导致重复释放内存,从而产生上述问题。所以在调用destroy_LinkStack函数之后,确保不再使用该内存块,避免重复释放。

二、源代码 

#include 
#include 
#include 
#include 
using namespace std;

struct stackNode {
	struct stackNode* next;
};

struct LStack {
	struct stackNode pHeader;  //不用指针类型,因为内存在malloc时已经给它分配好了
	int m_Size;
};

typedef void* LinkStack;

void* init_LinkStack() {
	struct LStack* stack = (struct LStack*)malloc(sizeof(struct LStack));
	if (stack == NULL) {
		perror("create error");
		return NULL;
	}

	stack->pHeader.next = NULL;
	stack->m_Size = 0;

	return stack;
}

void push_LinkStack(LinkStack stack, void* data) {
	if (stack == NULL) {
		return;
	}
	struct LStack* myStack = (struct LStack*)stack;

	struct stackNode* newNode = (struct stackNode*)data;

	newNode->next = myStack->pHeader.next;
	myStack->pHeader.next = newNode;

	myStack->m_Size++;
}

void pop_LinkStack(LinkStack stack) {
	if (stack == NULL) {
		return;
	}
	struct LStack* myStack = (struct LStack*)stack;

	if (myStack->m_Size == 0) {
		cout << "栈空,出栈失败" << endl;
		return;
	}
	struct stackNode* popNode = myStack->pHeader.next;
	myStack->pHeader.next = popNode->next;


	myStack->m_Size--;
}

void* top_LinkStack(LinkStack stack) {
	if (stack == NULL) {
		return NULL;
	}
	struct LStack* myStack = (struct LStack*)stack;

	if (myStack->m_Size == 0) {
		cout << "栈空,故栈顶为空" << endl;
		return NULL;
	}

	return myStack->pHeader.next;
}

int size_LinkStack(LinkStack stack) {
	if (stack == NULL) {
		return -1;
	}
	struct LStack* myStack = (struct LStack*)stack;
	return myStack->m_Size;
}

//判断是否为空
int isEmpty_LinkStack(LinkStack stack)
{
	if (stack == NULL)
	{
		return -1;
	}
	struct LStack* myStack = (struct LStack*)stack;

	if (myStack->m_Size == 0)
	{
		return 1;
	}

	return 0;
}

//销毁
void destroy_LinkStack(LinkStack stack)
{
	if (stack == NULL)
	{
		return;
	}
	free(stack);
	stack = NULL;
}

struct Person {
	void* node;
	char name[32];
	int age;
};

void test01() {

	LinkStack stack = init_LinkStack();

	struct Person p1 = { NULL , "p1" , 20 };
	struct Person p2 = { NULL , "p2" , 21 };
	struct Person p3 = { NULL , "p3" , 22 };
	struct Person p4 = { NULL , "p4" , 23 };
	struct Person p5 = { NULL , "p5" , 24 };


	push_LinkStack(stack, &p1);
	push_LinkStack(stack, &p2);
	push_LinkStack(stack, &p3);
	push_LinkStack(stack, &p4);
	push_LinkStack(stack, &p5);

	printf("共有%d个元素", size_LinkStack(stack));

	while (isEmpty_LinkStack(stack) == 0) {
		struct Person* p = (struct Person*)top_LinkStack(stack);
		printf("栈顶元素是:name = [%s] , age = [%d]\n", p->name, p->age);
		pop_LinkStack(stack);
	}


	printf("共有%d个元素", size_LinkStack(stack));

	destroy_LinkStack(stack);


}

int main() {
	test01();

	return 0;
}

共有5个元素栈顶元素是:name = [p5] , age = [24]
栈顶元素是:name = [p4] , age = [23]
栈顶元素是:name = [p3] , age = [22]
栈顶元素是:name = [p2] , age = [21]
栈顶元素是:name = [p1] , age = [20]
共有0个元素

你可能感兴趣的:(数据结构,c语言,c++,算法)