今天我们学习了内存管理和链表相关内容。
一.内存管理:
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"存放到堆区空间,完成打印
2.内存溢出:
内存溢出也称为内存越界
3.内存泄露:
程序中malloc的空间没有被释放
4.内存碎片:
由于频繁申请和释放,导致连续的空间分散成一些小的碎片空间,当malloc超过碎片空间时,则无法获得该空间(空间不连续),将这样的空间称为内存碎片
二、链表
链表是一种由指针和数据组合而成的一种存放数据的方式,优点是其中不同项数据存放不连续,节省空间。
1.有头链表的创建
typedef struct node
{
DataType Data;
struct node *pNext;
}LinkNode;
LinkNode *CreateLinkList(void)
{
LinkNode *pTmpNode = NULL;
pTmpNode = malloc(sizeof(LinkNode));
if (NULL == pTmpNode)
{
return NULL;
}
pTmpNode->pNext = NULL;
return pTmpNode;
}
这样我们就分别构建了链表每一项LinkNode和链表表头的创建函数CreateLinkList。之后只需在main主体里定义LinkNode类型的变量,再将CreateLinkList的值赋给变量即可。
2.头插法
int InsertHeadLinkList(LinkNode *pHead, DataType TmpData)
{
LinkNode *pTmpNode = NULL;
pTmpNode = malloc(sizeof(LinkNode));
if (NULL == pTmpNode)
{
return -1;
}
pTmpNode->Data = TmpData;
pTmpNode->pNext = pHead->pNext;
pHead->pNext = pTmpNode;
return 0;
}
通过调用这样的函数,再将所需的值传入形参,便可实现在链表头后插入数据。
3.链表数据的更新
int ReplaceLinkList(LinkNode *pHead, DataType OldData, DataType NewData)
{
LinkNode *pTmpNode = NULL;
pTmpNode = pHead->pNext;
while (pTmpNode != NULL)
{
if (pTmpNode->Data == OldData)
{
pTmpNode->Data = NewData;
}
pTmpNode = pTmpNode->pNext;
}
return 0;
}
4.链表的删除与销毁
int DeleteLinkList(LinkNode *pHead, DataType TmpData)
{
LinkNode *pPreNode = NULL;
LinkNode *pTmpNode = NULL;
pTmpNode = pHead->pNext;
pPreNode = pHead;
while (pTmpNode != NULL)
{
if (pTmpNode->Data == TmpData)
{
pPreNode->pNext = pTmpNode->pNext;
free(pTmpNode);
pTmpNode = pPreNode->pNext;
}
else
{
pTmpNode = pTmpNode->pNext;
pPreNode = pPreNode->pNext;
}
}
return 0;
}
int DestroyLinkList(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;
}