动态内存管理与柔性数组2

简介: 动态内存管理与柔性数组

4.题目练习

真张图中的p还涉及到内存泄漏,p动态内存开辟了空间,但是没有使用,也没有释放,出函数后这块动态内存开辟的空间还存在,但是已经无法访问和释放了

5.c/c++的内存开辟

这里借用一张图

C/C++程序内存分配的几个区域:

1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。

2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。

3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。

4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。

       普通的局部变量是在栈区 分配空间的,栈区的特点是在上面创建的变量出了作用域就销毁。 但是被static 修饰的变量存放在 数据段(静态区) ,数据段的特点是在上面创建的变量,直到程序 结束才销毁,所以生命周期变长。

6.柔性数组

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

        6.1柔性数组的特点      

  • 结构中的柔性数组成员前面必须至少一个其他成员。
  • sizeof 返回的这种结构大小不包括柔性数组的内存。
  • 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

       6.2柔性数组的使用

struct st
{
  int a;
  int b[];//柔性数组
};
int main()
{
  struct st* s = (struct st*)malloc(sizeof(struct st) + 40);//a占4个字节,给b开辟40个字节,一共开辟44字节大小的空间
  if (s == NULL)
  {
    perror("malloc");
    return 1;
  }
  s->a = 100;
  int i = 0;
  for ( i = 0; i < 10; i++)
  {
    s->b[i] = i + 1;
  }
  //如果遇到空间不够,继续增容
  struct st* p = (struct st*)realloc(s, sizeof(struct st) + 80);
  if (p == NULL)
  {
    perror("realloc");
    return 1;
  }
  s = p;
  p = NULL;
  s->a = 99;
  for (i = 0; i < 15; i++);
  {
    printf("%d\n", s->b[i]);
  }
  free(s);
  s = NULL;
  return 0;
}

    6.3柔性数组的优势

第一个好处是:方便内存释放如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给 用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。


第二个好处是: 这样有利于访问速度, 连续的内存有益于提高访问速度,也有益于减少内存碎片

目录
相关文章
|
存储 编译器 Go
数组在内存中的存储
数组在内存中的存储
119 0
|
3月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
3月前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
4月前
|
Rust 安全 Java
内存数组越界
【10月更文挑战第14天】
53 1
|
5月前
|
编译器 Linux API
基于类型化 memoryview 让 Numpy 数组和 C 数组共享内存
基于类型化 memoryview 让 Numpy 数组和 C 数组共享内存
77 0
|
5月前
|
存储 安全 Linux
将文件映射到内存,像数组一样访问
将文件映射到内存,像数组一样访问
53 0
|
9月前
|
Java
<Java SE> 5道递归计算,创建数组,数组遍历,JVM内存分配...
<Java SE> 5道递归计算,创建数组,数组遍历,JVM内存分配
82 2
|
存储 JavaScript 前端开发
手撕前端面试题【javascript~ 列表动态渲染、无重复数组、数组排序、新数组、创建数组、深浅拷贝、内存泄露等】
html页面的骨架,相当于人的骨头,只有骨头是不是看着有点瘆人,只有HTML也是如此。 css,相当于把骨架修饰起来,相当于人的皮肉。
100 0
|
9月前
|
存储 编译器 C语言
C陷阱:数组越界遍历,不报错却出现死循环?从内存解析角度看数组与局部变量之“爱恨纠葛”
在代码练习中,通常会避免数组越界访问,但如果运行了这样的代码,可能会导致未定义行为,例如死循环。当循环遍历数组时,如果下标超出数组长度,程序可能会持续停留在循环体内。这种情况的发生与数组和局部变量(如循环变量)在内存中的布局有关。在某些编译器和环境下,数组和局部变量可能在栈上相邻存储,数组越界访问可能会修改到循环变量的值,导致循环条件始终满足,从而形成死循环。理解这种情况有助于我们更好地理解和预防这类编程错误。
192 0
|
9月前
|
存储 机器学习/深度学习 Java
【Java探索之旅】数组使用 初探JVM内存布局
【Java探索之旅】数组使用 初探JVM内存布局
86 0

热门文章

最新文章