堆栈顺序存储和 free 失败原因分析

*** Error in `./a.out': free(): invalid pointer: 0x09e7c018 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767c2)[0xb76307c2]
/lib/i386-linux-gnu/libc.so.6(+0x77510)[0xb7631510]
./a.out[0x804864c]
./a.out[0x8048830]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb75d3905]
./a.out[0x8048431]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 655787     /home/zuopeng/Desktop/c/a.out
08049000-0804a000 r--p 00000000 08:01 655787     /home/zuopeng/Desktop/c/a.out
0804a000-0804b000 rw-p 00001000 08:01 655787     /home/zuopeng/Desktop/c/a.out
09e7c000-09e9d000 rw-p 00000000 00:00 0          [heap]
b7589000-b75a4000 r-xp 00000000 08:01 918479     /lib/i386-linux-gnu/libgcc_s.so.1
b75a4000-b75a5000 r--p 0001a000 08:01 918479     /lib/i386-linux-gnu/libgcc_s.so.1
b75a5000-b75a6000 rw-p 0001b000 08:01 918479     /lib/i386-linux-gnu/libgcc_s.so.1
b75b9000-b75ba000 rw-p 00000000 00:00 0 
b75ba000-b7768000 r-xp 00000000 08:01 918454     /lib/i386-linux-gnu/libc-2.17.so
b7768000-b776a000 r--p 001ae000 08:01 918454     /lib/i386-linux-gnu/libc-2.17.so
b776a000-b776b000 rw-p 001b0000 08:01 918454     /lib/i386-linux-gnu/libc-2.17.so
b776b000-b776e000 rw-p 00000000 00:00 0 
b777f000-b7783000 rw-p 00000000 00:00 0 
b7783000-b7784000 r-xp 00000000 00:00 0          [vdso]
b7784000-b77a4000 r-xp 00000000 08:01 918430     /lib/i386-linux-gnu/ld-2.17.so
b77a4000-b77a5000 r--p 0001f000 08:01 918430     /lib/i386-linux-gnu/ld-2.17.so
b77a5000-b77a6000 rw-p 00020000 08:01 918430     /lib/i386-linux-gnu/ld-2.17.so
bf85a000-bf87b000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)
<span style="font-family:Arial;color:#333333;"><span style="font-size: 14px; line-height: 26px;">错误代码如下:</span></span>
<span style="font-family:Arial;color:#333333;"><span style="font-size: 14px; line-height: 26px;"></span></span><pre name="code" class="cpp">//顺序存储
//Written by ZP1015
//2015.10.19

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



struct STACK_NODE
{
    int* pData;/*数组,长度为StackLenMax*/
    int top;//栈顶指针的位置
    int StackLenMax;
};

struct STACK_NODE* alloc_stack(int StackSize)
{
    
    if(StackSize <= 0)
        return NULL;
	
	struct STACK_NODE* pStackNode = NULL;
	
    pStackNode = (struct STACK_NODE*)malloc(sizeof(struct STACK_NODE));
    if(NULL == pStackNode) {
		return NULL;
    }
	
    memset(pStackNode, 0, sizeof(struct STACK_NODE));

    pStackNode->pData = (int *)malloc(sizeof(int)*StackSize);
    if(NULL == pStackNode->pData){
		goto malloc_failed;
    }
	
	printf("%d\n",pStackNode->pData);
	
    memset(pStackNode->pData, 0, sizeof(int) * StackSize);
    pStackNode->top= -1; /*初始化从0开始*/
	pStackNode->StackLenMax = StackSize;
	
    return pStackNode;

malloc_failed:
	free(pStackNode);
	return NULL;
}

int free_stack(struct STACK_NODE* pStackNode)
{
    if(NULL == pStackNode)
        return -1;

    if(NULL == pStackNode->pData) {
		return -1;
	}
	printf("%d\n",pStackNode->pData);
	printf("[%d] %d\n",__LINE__,pStackNode->pData[2]);
    free(pStackNode->pData);
    free(pStackNode);
	
    return 0;
}

int stack_push(struct STACK_NODE* pStackNode, int value)
{
	/*1.异常处理*/
    if(NULL == pStackNode)
        return -1;
	if(NULL == pStackNode->pData) {
		return -1;
	}
	
	/*2.栈满,不能压入元素*/
    if(pStackNode->top == pStackNode->StackLenMax-1)
        return -1;
	printf("%d\n",pStackNode->top);
    pStackNode->pData[pStackNode->top++] = value;

    return 0;
}

int stack_pop(struct STACK_NODE* pStackNode, int* value)
{
    if(NULL == pStackNode || NULL == value)
        return -1;

    if(-1 == pStackNode->top)
        return -1;

    *value = pStackNode->pData[pStackNode->top--];
	
    return 0;
}

int count_stack_number(struct STACK_NODE* pStackNode)
{
    return (pStackNode->top+1);
}

void print_stack_node(struct STACK_NODE *pStackNode) 
{
	/*1.输入的参数有误*/
    if(NULL == pStackNode) {
		printf("[%d] pStackNode is illegal! \n",__LINE__);
		return;
    }
	/*2.输入的链式堆栈为空*/
	if(-1 == pStackNode->top) {
		printf("[%d] pStackNode is empty!\n",__LINE__);
		return ;
	}
	
	struct STACK_NODE *pStackNodeTemp = pStackNode;
	int count = 0;
	
	while(count <= pStackNode->top) {
		printf("%d ",pStackNodeTemp->pData[count]);
		count++;;
	}
	printf("\n");
}


int main()
{
	struct STACK_NODE *pStackNode;
	pStackNode = alloc_stack(20);
	int i = 0;
	for (i = 0;i<10;i++) {
		stack_push(pStackNode,i);
	}
	print_stack_node(pStackNode);


	free_stack(pStackNode);

	getchar();
	getchar();
	
	return 0;
}

 

你是否遇到过这样的情况,真是要疯了。程序总是无端coredump,gdb到core文件里面也看不出个所以然来,排查了一下午也没找到所以然。

不过回过头好好想想,内存问题始终是程序员需要去面对的问题,通常我们会犯的内存问题大概有以下几种:

  1. 内存重复释放,出现double free时,通常是由于这种情况所致。
  2. 内存泄露,分配的内存忘了释放。
  3. 内存越界使用,使用了不该使用的内存。
  4. 使用了无效指针。
  5. 空指针,对一个空指针进行操作。

我们针对上述几种情况逐一排查,最后发现了是属于第三种情况,造成free失败。在 alloc_stack 中我把栈顶指针从-1开始计算,栈顶元素数组从-1开始操作,因此造成了这个 coredump 问题。

//顺序存储
//Written by ZP1015
//2015.10.19

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



struct STACK_NODE
{
    int* pData;/*数组,长度为StackLenMax*/
    int top;//栈顶指针的位置
    int StackLenMax;
};

struct STACK_NODE* alloc_stack(int StackSize)
{
    
    if(StackSize <= 0)
        return NULL;
	
	struct STACK_NODE* pStackNode = NULL;
	
    pStackNode = (struct STACK_NODE*)malloc(sizeof(struct STACK_NODE));
    if(NULL == pStackNode) {
		return NULL;
    }
	
    memset(pStackNode, 0, sizeof(struct STACK_NODE));

    pStackNode->pData = (int *)malloc(sizeof(int)*StackSize);
    if(NULL == pStackNode->pData){
		goto malloc_failed;
    }
	
	printf("%d\n",pStackNode->pData);
	
    memset(pStackNode->pData, 0, sizeof(int) * StackSize);
    pStackNode->top= -1; /*初始化从0开始*/
	pStackNode->StackLenMax = StackSize;
	
    return pStackNode;

malloc_failed:
	free(pStackNode);
	return NULL;
}

int free_stack(struct STACK_NODE* pStackNode)
{
    if(NULL == pStackNode)
        return -1;

    if(NULL == pStackNode->pData) {
		return -1;
	}
	printf("%d\n",pStackNode->pData);
	printf("[%d] %d\n",__LINE__,pStackNode->pData[2]);
    free(pStackNode->pData);
    free(pStackNode);
	
    return 0;
}

int stack_push(struct STACK_NODE* pStackNode, int value)
{
	/*1.异常处理*/
    if(NULL == pStackNode)
        return -1;
	if(NULL == pStackNode->pData) {
		return -1;
	}
	
	/*2.栈满,不能压入元素*/
    if(pStackNode->top == pStackNode->StackLenMax-1)
        return -1;
	printf("%d\n",pStackNode->top);
    pStackNode->pData[++pStackNode->top] = value;

    return 0;
}

int stack_pop(struct STACK_NODE* pStackNode, int* value)
{
    if(NULL == pStackNode || NULL == value)
        return -1;

    if(-1 == pStackNode->top)
        return -1;

    *value = pStackNode->pData[pStackNode->top--];
	
    return 0;
}

int count_stack_number(struct STACK_NODE* pStackNode)
{
    return (pStackNode->top+1);
}

void print_stack_node(struct STACK_NODE *pStackNode) 
{
	/*1.输入的参数有误*/
    if(NULL == pStackNode) {
		printf("[%d] pStackNode is illegal! \n",__LINE__);
		return;
    }
	/*2.输入的链式堆栈为空*/
	if(-1 == pStackNode->top) {
		printf("[%d] pStackNode is empty!\n",__LINE__);
		return ;
	}
	
	struct STACK_NODE *pStackNodeTemp = pStackNode;
	int count = 0;
	
	while(count <= pStackNode->top) {
		printf("%d ",pStackNodeTemp->pData[count]);
		count++;;
	}
	printf("\n");
}


int main()
{
	struct STACK_NODE *pStackNode;
	pStackNode = alloc_stack(20);
	int i = 0;
	for (i = 0;i<10;i++) {
		stack_push(pStackNode,i);
	}
	print_stack_node(pStackNode);


	free_stack(pStackNode);

	getchar();
	getchar();
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂奔的乌龟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值