admin管理员组文章数量:1487745
动态内存管理学不懂,小代老师带你深入理解动态内存管理(下卷)
柔性数组
也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。 C99 中,结构中的最后⼀个元素允许是未知⼤⼩的数组,这就叫做『柔性数组』成员。 例如:
代码语言:javascript代码运行次数:0运行复制struct st_type
{
int i;
int a[0];//柔性数组成员
};
有些编译器会报错⽆法编译可以改成:
代码语言:javascript代码运行次数:0运行复制struct st_type
{
int i;
int a[];//柔性数组成员
};
6.1 柔性数组的特点:
• 结构中的柔性数组成员前⾯必须⾄少⼀个其他成员。 • sizeof 返回的这种结构⼤⼩不包括柔性数组的内存。 • 包含柔性数组成员的结构⽤malloc ()函数进⾏内存的动态分配,并且分配的内存应该大于结构的大 小,以适应柔性数组的预期⼤⼩。
代码语言:javascript代码运行次数:0运行复制typedef struct st_type
{
int i;
int a[0];//柔性数组成员
}type_a;
int main()
{
printf("%d\n", sizeof(type_a));//输出的是4
return 0;
}
6.2 柔性数组的使用
代码语言:javascript代码运行次数:0运行复制#include<stdio.h>
#include<stdlib.h>
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;
}
代码语言:javascript代码运行次数: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就可以把所有的内存也给释放掉。 第⼆个好处是:这样有利于访问速度. 连续的内存有益于提⾼访问速度,也有益于减少内存碎⽚。(其实,我个⼈觉得也没多⾼了,反正你 跑不了要⽤做偏移量的加法来寻址)
扩展阅读: C语言结构体里面的指针和数组
7. 总结C/C++中程序内存区域划分
C/C++程序内存分配的⼏个区域:
- 栈区(stack):在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内 存容量有限。 栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。 《函数栈帧的创建和销毁》
- 堆区(heap):⼀般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配⽅ 式类似于链表。
- 数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。
- 代码段:存放函数体(类成员函数和全局函数)的⼆进制代码。
本文标签: 动态内存管理学不懂,小代老师带你深入理解动态内存管理(下卷)
版权声明:本文标题:动态内存管理学不懂,小代老师带你深入理解动态内存管理(下卷) 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/shuma/1754748435a3179119.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论