C语言 malloc分配地址 | 青训营

273 阅读4分钟

C语言malloc动态分配空间

一、动态内存管理概述

在C语言编程过程中,经常需要处理数据量不确定的情况,例如处理用户输入或进行文件操作,这时我们不可能在编程时就确定需要多少内存。动态内存管理功能就可以在程序运行过程中按需分配或释放内存。

在C语言中,主要使用malloccallocreallocfree等函数进行动态内存管理。本篇笔记主要讲解malloc函数的使用。

首先定义一个char *a 指针a指向空指针,把a值传递到函数Init中,这时候a传递的是本身的地址,而不是指针a的地址,如果传到函数里面,改变则是改变指针a里面的值的内容,但是指针a的地址是无法改变的。如果要改变指针a的地址便是传指针a的地址。

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

void Init(char* p)
{
	*p = 'b';//先修改a指向的地址b
	char c;
	p = c;//这个是修改a的地址
}

void main()
{
	char b = 'a';
	char* a = &b;
	Init(a);
	free(a);
}

image.png

这里可以看到虽然在函数里面p的地址是改变的但是退出函数以后,a的地址还是没有改变的,但是a指向的b的值是发生了改变 证明Init(a)传了本身的地址过去,但是传的不是指针a的地址,所以无法改变指针a的地址。

但是p销毁以后mallc出来的空间就在堆空间里面存放着,但是没有人牵引。

如果传指针a的地址的话就能够改变指针a的地址 &a

二、malloc函数

malloc函数在stdlib.h库中,它的原型如下:

void* malloc (size_t size);

malloc函数会向系统请求分配指定大小(字节数)的连续空间,并返回这块空间的首地址。如果分配成功,返回非NULL指针;如果分配失败,返回NULL。

注意,malloc函数分配的内存是未初始化的,其内容是未知的。

三、使用malloc函数分配内存

使用malloc函数分配内存非常简单,只需指定需要的字节数:

int *p = (int*) malloc(sizeof(int)*10); //分配40个字节,可以存储10个int类型数据

上述代码向系统申请40个字节的内存,并把内存首地址赋给p。若分配成功,则p指向了一个由10个int大小的连续空间。否则,p将会是NULL。

四、使用malloc函数注意事项

虽然用malloc进行内存分配看似简单,但是在实际使用中还需要注意以下几点:

  1. 验证malloc的返回值:分配内存可能失败,程序应检查malloc的返回值是否为NULL。
int *p = (int*) malloc(sizeof(int)*10);
if(p == NULL){
    printf("内存分配失败!\n");
    exit(1);
}
  1. 记得释放内存:使用完动态分配的内存后,要手动通过free函数释放,否则会导致内存泄漏。
free(p);
p = NULL; // 避免野指针
  1. 避免越界访问:分配的内存大小有限,注意不要越界访问,否则会导致不可预期的问题。

五、使用malloc创建复合类型

malloc不只可以用于创建简单的数据类型,还可以用于创建复杂的数据结构,例如结构体和数组。

例如,创建结构体数组:

typedef struct {
    int id;
    char name[20];
} Student;

Student *p = (Student*) malloc(sizeof(Student)*10);

此段代码创建了一个可以存储10个Student结构体的数组。每一个元素都可以像普通的结构体一样操作:

p[0].id = 1;
strcpy(p[0].name, "张三");

同样,记得在使用结束后释放内存。

六、malloc和calloc

除了malloc,C语言中还有calloc函数,和malloc相比,calloc在分配内存后会自动将内存初始化为0。

它的原型是:

void* calloc (size_t n, size_t size);

其中,n表示需要分配的元素数量,size表示每个元素的大小。可以看出,calloc是按元素数量进行分配,而malloc是直接按字节分配。

七、总结

动态内存管理是C语言的重要特性,掌握malloc函数的使用对理解和利用这一特性至关重要。正确使用malloc可以大大提升C语言编程的灵活性和效率,但也需要注意正确验证分配结果和及时释放内存,避免出现内存泄漏和其他问题。