动态内存管理学不懂,小代老师带你深入理解动态内存管理(下卷)

动态内存管理学不懂,小代老师带你深入理解动态内存管理(下卷

  • 柔性数组
    • 6.1 柔性数组的特点:
    • 6.2 柔性数组的使用
  • 7. 总结C/C++中程序内存区域划分

柔性数组

也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。
C99 中,结构中的最后⼀个元素允许是未知⼤⼩的数组,这就叫做『柔性数组』成员。
例如:

struct st_type
{
 int i;
 int a[0];//柔性数组成员
};

有些编译器会报错⽆法编译可以改成:

struct st_type
{
 int i;
 int a[];//柔性数组成员
};

6.1 柔性数组的特点:

• 结构中的柔性数组成员前⾯必须⾄少⼀个其他成员。
• sizeof 返回的这种结构⼤⼩不包括柔性数组的内存。
• 包含柔性数组成员的结构⽤malloc ()函数进⾏内存的动态分配,并且分配的内存应该大于结构的大
,以适应柔性数组的预期⼤⼩。

typedef struct st_type
{
 int i;
 int a[0];//柔性数组成员
}type_a;
int main()
{
 printf("%d\n", sizeof(type_a));//输出的是4
 return 0;
}

6.2 柔性数组的使用

#include
#include
typedef struct un 
{
	int c;
	char a;
	int arr [0];
}sort;
int main()
{
	sort* p = (sort*malloc(sizeof(sort)+ sizeof(int) * 10);
	if (p == NULL)
	{
		perror(malloc);
		return 1;
	}
	p->a = 'a';
	p->c = 100;
	for (int i = 0; i < 10; i++)
	{
		p->arr[i] = i;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d", p->arr[i]);
	}
	sort* s = realloc(p, sizeof(sort) + 40 * sizeof(int));
	if (s != NULL)
	{
		p = s;
		s = NULL;
	}
	else
	{
		return 1;
	}
	for (int i = 0; i < 40; i++)
	{
		printf("%d", p->arr[i]);
	}
	free(p);
	p == NULL;
	return 0;
}
struct s
{
	int a;
	int* arr;
};
int mian()
{
	struct s* ps = (struct s*) malloc (sizeof(struct s));
	if (ps == NULL)
	{
		perror("malloc");
		return 1;
	}
	int* temp = (int*)malloc(10 * sizeof(int));
	if(temp!=NULL)
	{
		ps->arr = temp;
		temp = NULL;
	}
	else
	{
		return 1;
	}
	ps->a = 100;
	for (int i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//调整空间
	temp = (int*) realloc (ps->arr ,sizeof(int) * 20);
	if (temp != NULL)
	{
		ps->arr=temp;
		temp = NULL;
	}
	else
	{
		perror("realloc");
		return 1;
	}
	for (int i = 0; i < 40; i++)
	{
		printf("%d", ps->arr[i]);
	}
	free(ps->arr);
	ps = NULL;
	free(ps->a);
	ps->a = NULL;

}

上述 代码1 和 代码2 可以完成同样的功能,但是 ⽅法1 的实现有两个好处:
第⼀个好处是:⽅便内存释放
如果我们的代码是在⼀个给别⼈⽤的函数中,你在⾥⾯做了⼆次内存分配,并把整个结构体返回给⽤
⼾。⽤⼾调⽤free可以释放结构体,但是⽤⼾并不知道这个结构体内的成员也需要free,所以你不能
指望⽤⼾来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存⼀次性分配好了,并返
回给⽤⼾⼀个结构体指针,⽤⼾做⼀次free就可以把所有的内存也给释放掉。
第⼆个好处是:这样有利于访问速度.
连续的内存有益于提⾼访问速度,也有益于减少内存碎⽚。(其实,我个⼈觉得也没多⾼了,反正你
跑不了要⽤做偏移量的加法来寻址)
动态内存管理学不懂,小代老师带你深入理解动态内存管理(下卷)_第1张图片
扩展阅读:
C语言结构体里面的指针和数组

7. 总结C/C++中程序内存区域划分

动态内存管理学不懂,小代老师带你深入理解动态内存管理(下卷)_第2张图片
C/C++程序内存分配的⼏个区域:

  1. 栈区(stack):在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时
    这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内
    存容量有限。 栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。
    《函数栈帧的创建和销毁》
  2. 堆区(heap):⼀般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配⽅
    式类似于链表。
  3. 数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。
  4. 代码段:存放函数体(类成员函数和全局函数)的⼆进制代码。

你可能感兴趣的:(C语言,算法,数据结构)