关于c语言中的动态内存分配的问题(malloc、calloc、realloc、free,以及柔性数组)

关于c语言中的动态内存分配,是一个非常重要的部分,在数据结构中使用的十分频繁。今天就来讲一讲动态内存分配中会使用到的函数以及一些需要注意的事项。

会使用到的一些函数

动态内存分配就是程序运行过程中,向堆区申请空间。所以C语言对外提供了一些函数,下面这些函数都包含在 stdlib.h 和 malloc.h 中

malloc和calloc

void* malloc(size_t Size);
void* calloc(size_t _Count, size_t Size);

这两个函数本质上都是用来申请空间的,区别在于:

malloc函数只会申请Size字节大小的空间,并返回这块空间的起始地址。

calloc函数是申请 _Count 个 Size 大小的空间,将这些空间都初始化成0之后,返回这块空间的额首地址。

注意:

1、因为这些函数返回的都是 void* ,所以在接受之前要将地址强转成需要的类型指针。

2、申请空间失败时,malloc和calloc会返回NULL,所以,动态分配的空间要判断是否为空之后再用,以免发生空指针异常。

例如:

关于c语言中的动态内存分配的问题(malloc、calloc、realloc、free,以及柔性数组)_第1张图片

 free

void free( void *memblock );

free函数是用来对动态申请的空间进行释放的,。

其实动态申请的空间在程序结束的时候,系统会自己回收这些空间,但是如果在一个长时间运行的系统中,申请的空间如果在没有指针指向他们的时候,那他们就不会自己释放掉,已然占据着堆内存的空间,想要回收这些空间只能靠重启程序,这显然不现实。这种情况就叫做内存泄露。所以要养成一个良好的开发习惯:动态申请的空间在不用的时候,要手动将其释放掉,将使用权归还给系统。

注意:

1、free函数的参数不能是NULL;

2、free函数的参数不能是动态申请空间的部分,比如:

void test2() {
	int* arr = (int*)malloc(sizeof(int) * 10);
	arr += 5;
	free(arr);
}

这样的程序在执行过程中会被中止,这样的代码是错误的;

realloc

void* realloc (void* ptr, size_t size);

realloc函数是用来对动态申请的空间进行扩容或者缩小的一些大小调整用的。ptr 是要调整的内存地址,size是调整之后的新大小,返回值为调整大小之后的起始地址。

注意:

1、同样的,返回的地址是 void* 类型的地址,需要进行强制类型转换;

2、另外,还需要注意,在进行扩容调整的过程中,原本在堆区申请到的空间后面有足够的空间来进行扩容,那么会直接在将后面的空间分配给程序。如果原本在堆区申请到的空间后面没有足够的,用来扩容的空间,这个时候,realloc函数会在堆区有足够的空间的地方申请一块足够大的空间,对原本的数据进行迁移,然后在将原本的空间free掉,返回新开辟的空间的首地址。

3、realloc函数在扩容失败时,同样会返回NULL,和分配空间不同,realloc更要防止一下写法,以免在扩容空间失败时,丢失之前的数据:

int* arr = (int*)malloc(sizeof(int) * 10);
arr = realloc(arr, sizeof(int) * 10);

在赋值的时候应该:

int* arr = (int*)malloc(sizeof(int) * 10);
int* temp = realloc(arr, sizeof(int) * 10);
if (temp == NULL) {
	perror("realloc:");
	return 1;
}
arr = temp;

柔性数组

在C99标准中,添加了个叫做柔性数组的点:

在结构体中,最后一个元素允许是未知大小的数组,这叫做柔性数组成员。

结构中的柔性数组成员前面必须至少一个其他成员。

sizeof 返回的这种结构大小不包括柔性数组的内存。

包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

typedef struct S {
	int a;
	int arr[];//柔性数组成员
}S;

void test4() {
	printf("%d\n", sizeof(S));
}

执行结果如下:

关于c语言中的动态内存分配的问题(malloc、calloc、realloc、free,以及柔性数组)_第2张图片

再例如:

typedef struct S {
	int a;
	int arr[];
}S;

void test4() {
	S* s1 = (S*)malloc(sizeof(S) + sizeof(int) * 10);
	s1->a = 10;
	for (int i = 0; i < 10; i++) {
		*(s1->arr + i) = i;
	}
	for (int i = 0; i < 10; i++) {
		printf("%d ", *(s1->arr + i));
	}
}

执行结果:

关于c语言中的动态内存分配的问题(malloc、calloc、realloc、free,以及柔性数组)_第3张图片

 好了,今天的分享就到这里了。

你可能感兴趣的:(c语言,柔性数组,开发语言)