嵌入式学习第十五天!(内存管理、链表)

本文详细介绍了内存管理中的malloc和free函数,讨论了内存溢出、内存泄露和内存碎片的概念,并通过链表示例展示了如何创建、操作和释放链表。此外,还提供了一个链表尾插法和字符串倒置的编程练习。
摘要由CSDN通过智能技术生成

1. 内存管理:

    1. malloc 

void *malloc(size_t size);

    功能:申请堆区空间

    参数:size:申请堆区空间的大小

    返回值:返回获得的空间的首地址,失败返回NULL

    2. free

void free(void *ptr);

    功能:释放堆区空间

    注意:

        1.free只能释放堆区空间

        2. 一个空间只能被free一次,多次free程序会崩溃

        3. malloc需要和free搭配使用,如果只有malloc没有free会内存泄露

    练习:要求申请堆区空间,将“hello world”存放到堆区空间,完成打印

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

int main(void)
{
	char *p = NULL;

	p = malloc(16);
	if(p == NULL)
	{
		printf("failed\n");
		return -1;
	}

	strcpy(p, "Hello World");

    printf("%s\n",p);

	free(p);

	return 0;
}

2. 内存溢出:

    内存溢出也称为内存越界

3. 内存泄露:

    程序中malloc的空间没有被释放

4. 内存碎片:

    由于频繁申请和释放,导致连续的空间分散成一些小的碎片空间,当malloc超过碎片空间时,则无法获得该空间(空间不连续),将这样的空间称为内存碎片

1. 链表

        1. 链表的构建

typedef int DataType;

typedef struct node
{
	DataType Data;
	struct node *pNext;
}LinkNode;

LinkNode *CreateLinkList(void)
{
	LinkNode *pTmpNode = NULL;

	pTmpNode = malloc(sizeof(LinkNode));
	if(pTmpNode == NULL)
	{
		return NULL;
	}

	pTmpNode->pNext = NULL;

	return pTmpNode;
}

        2. 链表的插入(头插法)

int InsertHeadLinkList(LinkNode * phead, DataType TmpData)
{
	LinkNode *pTmpNode = NULL;

	pTmpNode = malloc(sizeof(LinkNode));
	if(pTmpNode == NULL)
	{
		return -1;
	}

	pTmpNode->Data = TmpData;
	pTmpNode->pNext = phead->pNext;
	phead->pNext = pTmpNode;
	
	return 0;
}

        3. 链表的输出

int ShowLinkList(LinkNode *phead)
{
	LinkNode *pTmpNode = NULL;
	pTmpNode = phead->pNext;
	while(pTmpNode != NULL)
	{
		printf("%d ",pTmpNode->Data);
		pTmpNode = pTmpNode->pNext;
	}
	printf("\n");
	return 0;
}

        4. 链表值的替换

int ReplaceData(LinkNode *phead, int OldData, int NewData)
{
	LinkNode *pTmpNode = NULL;
	pTmpNode = phead->pNext;
	while(pTmpNode != NULL)
	{
		if(pTmpNode->Data == OldData)
		{
			pTmpNode->Data = NewData;
		}
		pTmpNode = pTmpNode->pNext;
	}

	return 0;
}

        5. 链表删除某个值

int DeleteLinkList(LinkNode *phead, DataType DeleteData)
{
	LinkNode *pPreNode = NULL;
	LinkNode *pTmpNode = NULL;

	pTmpNode = phead->pNext;
	pPreNode = phead;

	while(pTmpNode != NULL)
	{
		if(pTmpNode->Data == DeleteData)
		{
			pPreNode->pNext = pTmpNode->pNext;
			free(pTmpNode);
			pTmpNode = pPreNode->pNext;
		}
		else
		{
			pTmpNode = pTmpNode->pNext;
			pPreNode = pPreNode->pNext;
		}
	}
}

        6. 链表的释放

int DestoryLinkList(LinkNode **pphead)
{
	LinkNode *pTmpNode = NULL;
	LinkNode *pFreeNode = NULL;

	pTmpNode = pFreeNode = *pphead;
	while(pTmpNode != NULL)
	{
		pTmpNode = pTmpNode->pNext;
		free(pFreeNode);
		pFreeNode = pTmpNode;
	}
	*pphead = NULL;

	return 0;
}

作业:

        1. 封装函数在链表中实现尾插法

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

typedef int DataType;
typedef struct node
{
	DataType Data;
	struct node *pNext;
}LinkList;

LinkList *CreatLinkList()
{
	LinkList *pTmpNode = NULL;

	pTmpNode = malloc(sizeof(LinkList));
	if(pTmpNode == NULL)
	{
		return NULL;
	}
	pTmpNode->pNext = NULL;
	
	return pTmpNode;

}

int InsertTailLinkList(LinkList *pHead, DataType NewData)
{
	LinkList *pTmpNode = NULL;
	LinkList *pPotNode = NULL;
	
	pPotNode = pHead;
	pTmpNode = malloc(sizeof(LinkList));
	if(pTmpNode == NULL)
	{
		return -1;
	}

	pTmpNode->Data = NewData;
	pTmpNode->pNext = NULL;

	while(pPotNode->pNext != NULL)
	{
		pPotNode = pPotNode->pNext;
	}

	pPotNode->pNext = pTmpNode;

	return 0;

}

int ShowLinkList(LinkList *pHead)
{
	LinkList *pTmpNode = NULL;
	pTmpNode = pHead->pNext;
	while(pTmpNode != NULL)
	{
		printf("%d ", pTmpNode->Data);
		pTmpNode = pTmpNode->pNext;
	}
	printf("\n");
	return 0;
}

int DestoryLinkList(LinkList **pphead)
{
	LinkList *pTmpNode = NULL;
	LinkList *pFreeNode = NULL;

	pTmpNode = pFreeNode = *pphead;
	while(pTmpNode != NULL)
	{
		pTmpNode = pTmpNode->pNext;
		free(pFreeNode);
		pFreeNode = pTmpNode;
	}
	*pphead = NULL;
	return 0;
}

int main(void)
{
	LinkList *linklist = NULL;
	
	linklist = CreatLinkList();
	InsertTailLinkList(linklist, 1);
	InsertTailLinkList(linklist, 2);
	InsertTailLinkList(linklist, 3);
	InsertTailLinkList(linklist, 4);
	InsertTailLinkList(linklist, 5);
	ShowLinkList(linklist);
	DestoryLinkList(&linklist);
}

        2. 从终端接收一个字符,将字符串倒置后输出(用指针的方法):

                “how are you”  >  "you are how"

#include <stdio.h>

int Reverse(char *pstr)
{
	char *phead = NULL;
	char *ptail = NULL;
	char tmp = 0;

	phead = ptail = pstr;
	while(*ptail != '\0')
	{
		ptail++;
	}
	ptail--;

	while(phead < ptail)
	{
		tmp = *phead;
		*phead = *ptail;
		*ptail = tmp;

		phead++;
		ptail--;
	}
	return 0;
}

int ReverseStr(char *pstr)
{
	char *phead = NULL;
	char *ptail = NULL;
	char *tmp1 = NULL;
	char *tmp2 = NULL;
	char tmp = 0;

	Reverse(pstr);
	phead = ptail = pstr;
	while(*pstr != '\0')
	{
		while(*ptail != ' ' && *ptail != '\0')
		{
			ptail++;
		}
		ptail--;
		tmp1 = phead;
		tmp2 = ptail;
		while(tmp1 < tmp2)
		{
			tmp = *tmp1;
			*tmp1 = *tmp2;
			*tmp2 = tmp;
			tmp1++;
			tmp2--;
		}
		if (*ptail != '\0')
        {
            ptail = ptail + 2;
            phead = ptail;
        }
        else
        {
            break;
        }
	}
	
}

int main(void)
{
	char str[32] = "how are you";
	ReverseStr(str);
	printf("%s\n",str);
	return 0;
}

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值