鱼C论坛

 找回密码
 立即注册
查看: 1494|回复: 8

为什么不能释放堆区内存?

[复制链接]
发表于 2021-10-29 20:42:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zhenhaowa66 于 2021-11-2 11:28 编辑

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<string.h>

//节点的结构体
struct LinkNode {

        void* data;
        struct LinkNode* next;
};

//链表的结构体
struct LList {
        //头节点
        struct LinkNode pHead;
        //链表长度
        int M_Size;
};
//测试数据结构
struct Person {

        char name[32];
        int age;
};


//void* 别名
typedef void* LinkList;

//初始化链表
LinkList init_Linklist(void);

//遍历链表
void foreach_LinkList(LinkList list,void(*myPrint)(void*));

//按位置删除链表数据
void removeByPos_LinkList(LinkList list, int pos);

//按对比值删除链表数据
void removeByValue_LinkList(LinkList list, void* data, int(*myCompare_LinkList)(void*, void*));
//测试函数
void test01(void);



#include"mybook.h"

//打印输出回调函数
void myPrint(void* mylist) {

        struct Person* pdata = mylist;
        printf("姓名: %s 年龄: %d\n", pdata->name, pdata->age);
}

//数据对比回调函数
int myCompare_LinkList(void* data1, void* data2) {

        struct Person* p1 = data1;
        struct Person* p2 = data2;

        return (strcmp(p1, p2) == 0 && p1->age == p2->age);
}

//初始化链表
LinkList init_Linklist() {
        struct LList* mylist = malloc(sizeof(struct LList));
        if (mylist == NULL) {
                return NULL;
        }
        //给头节点属性初始化
        mylist->pHead.data = 0;
        mylist->pHead.next = NULL;
        mylist->M_Size = 0;

        return mylist;
}
//插入节点
void insert_LinkList(LinkList list,int pos,void* date) {

        if (list == NULL || date == NULL) {
                return NULL;
        }
        struct LList* mylist = list;
        if (mylist->M_Size < pos || pos < 0) {
                pos = mylist->M_Size;
        }

        //创建临时节点,通过循环找到待插入位置的前驱节点的位置
        struct LinkNode* pCurent = &mylist->pHead;
        for (int i = 0; i < pos; i++) {
                pCurent = pCurent->next;
        }
        //找到插入位置的前驱节点,创建新的节点
        struct LinkNode* newNode = malloc(sizeof(struct LinkNode));
        newNode->data = date;
        newNode->next = NULL;
        //插入连接
        newNode->next = pCurent->next;
        pCurent->next = newNode;
        //更新链表长度
        mylist->M_Size++;
}

//遍历链表
void foreach_LinkList(LinkList list,void(*myPrint)(void*)){

        if (list == NULL) {
                return NULL;
        }
        //还原链表真实结构体
        struct LList* mylist = list;
        struct LinkNode* pCurent = mylist->pHead.next;
        for (int i = 0; i < mylist->M_Size; i++) {
                myPrint(pCurent->data);
                pCurent = pCurent->next;
     }
}
//按位置删除链表数据
void removeByPos_LinkList(LinkList list, int pos) {
        struct LList* mylist = list;
        if (mylist->pHead.next == NULL || pos > mylist->M_Size || pos < 1){
                return NULL;
        }
        struct LinkNode* phead = &mylist->pHead;
        struct LinkNode* ptemp = phead;
       
        for (int i = 1; i <= pos; i++) {
                ptemp = ptemp->next;
                if(i>1)
                phead = phead->next;
        }
        phead->next = ptemp->next;
                free(ptemp);
          ptemp = NULL;
        mylist->M_Size--;

}
//按值删除链表数据
void removeByValue_LinkList(LinkList list,void* data, int(*myCompare_LinkList)(void*,void*)) {
        if (list == NULL || data == NULL) {
                return NULL;
        }
        struct LList* mylist = list;
        struct LinkNode* phead = &mylist->pHead;
        struct LinkNode* ptemp = phead;

        for (int i = 0; i <= mylist->M_Size; i++) {
                ptemp = ptemp->next;
                if (i >= 1)
                        phead = phead->next;
                if (myCompare_LinkList(ptemp->data ,data)){
                        phead->next = ptemp->next;
                                free(ptemp);
                                ptemp = NULL;
                        break;
                }
        }
        mylist->M_Size--;

}

//测试链表
void test01() {
        LinkList mylist = init_Linklist();
        struct LList* mydata = mylist;
        printf("链表现在有%d个节点!\n",mydata->M_Size );
        printf("----------------------------------------\n");
        struct Person p1 = { "刘备",25 };
        struct Person p2 = { "关羽",24 };
        struct Person p3 = { "张飞",23 };
        struct Person p4 = { "赵云",20 };
        struct Person p5 = { "马超",21 };
        struct Person p6 = { "黄忠",26 };
        struct Person p7 = { "诸葛亮",26 };
        struct Person p8 = { "魏延",22 };

        insert_LinkList(mylist, -1, &p1);
        insert_LinkList(mylist, 1, &p2);
        insert_LinkList(mylist, 2, &p3);
        insert_LinkList(mylist, 8, &p4);
        insert_LinkList(mylist, -3, &p5);
        insert_LinkList(mylist, 8, &p6);
        insert_LinkList(mylist, 1, &p7);
        insert_LinkList(mylist, 10, &p8);
        foreach_LinkList(mylist, myPrint);
        printf("链表现在有%d个节点!\n", mydata->M_Size);
        printf("----------------------------------------\n");

        removeByPos_LinkList(mylist, 2);
        foreach_LinkList(mylist, myPrint);
        printf("链表现在有%d个节点!\n", mydata->M_Size);
        printf("----------------------------------------\n");
        struct Person p = { "马超",21 };
        removeByValue_LinkList(mylist, &p, myCompare_LinkList);
        foreach_LinkList(mylist, myPrint);
        printf("链表现在有%d个节点!\n", mydata->M_Size);
        printf("----------------------------------------\n");

}

#include"mybook.h"


int main(){

        test01();


        return 0;
}

下面是运行结果;

链表现在有0个节点!
----------------------------------------
姓名: 刘备 年龄: 25
姓名: 诸葛亮 年龄: 26
姓名: 关羽 年龄: 24
姓名: 张飞 年龄: 23
姓名: 赵云 年龄: 20
姓名: 马超 年龄: 21
姓名: 黄忠 年龄: 26
姓名: 魏延 年龄: 22
链表现在有8个节点!
----------------------------------------
姓名: 刘备 年龄: 25
姓名: 关羽 年龄: 24
姓名: 张飞 年龄: 23
姓名: 赵云 年龄: 20
姓名: 马超 年龄: 21
姓名: 黄忠 年龄: 26
姓名: 魏延 年龄: 22
链表现在有7个节点!
----------------------------------------
姓名: 刘备 年龄: 25
姓名: 关羽 年龄: 24
姓名: 张飞 年龄: 23
姓名: 赵云 年龄: 20
姓名: 黄忠 年龄: 26
姓名: 魏延 年龄: 22
链表现在有6个节点!
----------------------------------------

D:\C-language\Clanguage\lian xi ce\Project1\Project1\Debug\Project1.exe (进程 5392)已退出
,代码为 0。
按任意键关闭此窗口. . .



现在修改好了没有问题了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-10-30 00:46:44 | 显示全部楼层
我不知道你这个 LinkList 是个指针还是类型啊?
如果不是指针的话   你这个肯定就不对了啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 08:48:18 | 显示全部楼层
本帖最后由 zhenhaowa66 于 2021-10-30 08:52 编辑
yuxijian2020 发表于 2021-10-30 00:46
我不知道你这个 LinkList 是个指针还是类型啊?
如果不是指针的话   你这个肯定就不对了啊


肯定是类型啊,不对哎哪里啊?

//void* 别名
typedef void* LinkList;



程序除了运行到free(ptemp)会报错提示一堆英文(检测到堆损坏......),就是不明白为什么会在这里提示出错,点击忽略,之后都可以正常运行,也可以达到预期的效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-30 08:58:12 | 显示全部楼层
你函数返回值明明是void  却  return NULL 编译器都没报错  说明你用的编译器版本很老  我建议你换个新版本的编译器试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 09:08:00 | 显示全部楼层
yuxijian2020 发表于 2021-10-30 08:58
你函数返回值明明是void  却  return NULL 编译器都没报错  说明你用的编译器版本很老  我建议你换个新版本 ...

编译器是VS2019
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-30 10:33:49 | 显示全部楼层
一般来说造成 堆栈损坏 的原因是 数组越界
或者说 是 对 申请空间以外的空间 进行了操作  才会报 堆栈损坏
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 11:20:26 | 显示全部楼层
yuxijian2020 发表于 2021-10-30 10:33
一般来说造成 堆栈损坏 的原因是 数组越界
或者说 是 对 申请空间以外的空间 进行了操作  才会报 堆栈损坏

那为什么程序运行正常,没有崩掉呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 15:16:13 | 显示全部楼层
有没有大佬出来指导下啊?是不是我的编译器设置没有设置好?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 16:03:48 | 显示全部楼层
下了个Dev_c++ 6.5的编译器运行了下,还是比较正常的,只有几个警告;应该是我的Vs2019 没有设置好的原因吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 19:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表