初步理解malloc与指针
malloc
void* malloc (size_t size);
分配 size 字节大小的空间,返回该空间首部的地址。
新分配的空间上的内容没有被初始化,仍然具有不确定的值。
如果 size 的大小为0,返回值取决于特定的库的实现(有可能是空指针,也有可能不是),但是返回的地址不应该被解引用。
分配成功返回首地址,分配失败返回NULL
头文件:<stdlib.h>
https://cplusplus.com/reference/cstdlib/malloc/?kw=malloc
为什么要有malloc?
malloc 和指针密切相关,我们知道指针是指向地址的变量,比如说有以下代码
#include <stdio.h>
int main(void)
{
int n = 0;
int* p = &n;
return 0;
}
内存中有个变量是 n,它的值为0,内存中还有个变量是 p,它的值为 n 的地址。注意,指针变量本身也在内存中占据一块空间,你可以再定义一个变量 p2 来指向这个指针的地址,这个变量 p2 就是所谓的二级指针,即指针的指针,你可以一直套下去,三级指针,四级指针…
#include <stdio.h>
int main(void)
{
int n = 0;
int* p = &n;
int** p2 = &p;
return 0;
}
那么为什么需要 malloc 呢?
道理很简单,指针变量的值是地址,地址对应着一块空间,没有空间,指针就不知道指向哪里,于是 malloc 起作用了,malloc可以分配一块空间,使指针指向这块空间开头的地址。并且,对于指针我们常常还伴有解引用操作,去操作某个地址上的值,如果这个地址不明确,这个指针不知道指向哪里,我们就没办法完成解引用的操作。
如果指针变量的值不是一个确定空间的地址,那么它就是野指针,我们要尽量避免野指针。
我在学习链表的过程中使用 malloc 时常常对以下代码感到困惑
LNode* p;
p->data = 100;
这样的代码是错误,p 是一个链表结点指针,你想要让 p->data 的值为100,可 p 根本不知道指向哪里,它就是个野指针,你再对这个不知道指向哪里的 p 进行操作,这当然不可以。我们需要让 p 指向一个实实在在的地方。
//方式一
LNode n;
LNode* p = &n;
p->data = 100;
//方式二
LNode* p = (LNode*)malloc(sizeof(LNode));
p->data = 100;
方式一是定义一个结点变量 n,系统会自动给它开辟空间,方式二是我们用 malloc 开辟一块空间,不管怎样,我们都是为了让指针指向一块确定的空间
其实上面的代码就和下面的代码一样
#include <stdio.h>
int main(void)
{
int* n;
*n = 1;
return 0;
}
同样的问题,n 不知道指向哪里
free
void free (void* ptr);
free 与 malloc 函数是配对使用的
首先一定要保证 free 函数中的参数 ptr 是指向 malloc 开辟的空间
其次,free 过后,ptr 可能仍然指向原来的地址,所以我们一般还需要令 ptr = NULL;
free 过后,我们就不能再使用这个 ptr 了,即使它仍指向原来的地址
浙公网安备 33010602011771号