C语言编程之动态内存与柔性数组的了解

 更新时间:2021年09月17日 10:24:06   作者:Booksort  
本文是C语言编程篇,这篇文章主要为大家介绍了C语言编程中动态内存的函数与柔性数组的特点,有需要的朋友可以借鉴参考下,希望可以有所帮助

创建变量
1,局部变量–栈区
2,全局变量–静态区
创建数组
1,局部数组–栈区
2,全局数组–静态区

在这里插入图片描述

介绍动态内存分配函数

malloc
free
calloc
realloc

所有的动态内存分配,都是在堆中进行分配
分别介绍动态内存函数
malloc

void* malloc(size_t size)

向内存堆中申请size个字节,并返回该空间的首地址。同时定义一个指针来接受函数返回的地址。
如:

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

开辟了40个字节的动态空间,进行了类型转换,就像开辟了10个int类型的空间。
如果开辟失败,就会返回一个空指针NULL。
所以,使用指针时要检查。否则会因空指针造成非法访问。
当动态空间不再使用时,就要将空间返回给内存,防止堆满了。

free
释放空间

void free(void* memblock(要释放的空间的首地址))

free只是释放掉堆中的空间,但定义的指针是在栈中,并不会被销毁,也就是说,指针储存的地址依然存在,所定义的指针仍然可以指向那个空间,但空间已经被销毁,不具备访问权限,会造成非法访问。

free(p);
p=NULL;

不仅释放空间,还要,将指针置为空指针,就无法访问了。

每次动态分配内存都要判断是否成功。

calloc
开辟一个数组空间,并将每个元素都置为0

void* calloc(size_t num,size_t size)

num代表是元素个数,size代表每个元素的字节数。calloc将在堆中开辟一个数组,并将每个元素都置为0.返回开辟空间的首地址。同时要考虑用一个对应指针来接受。

realloc
调整动态开辟空间的大小

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

举个例子

int* p=(int*)malloc(5*sizeof(int))
int* pp=(int*)realloc(p,10*sizeof(int))
if(p!=NULL&&pp!=NULL)
{
	p=pp;
}

这样使用后就会将p指向的空间调整为10个int空间的动态空间。
realloc使用细节

1,在堆区中,malloc开辟了一块空间,再使用realloc增加空间,诺可以满足直接在原空间直接增加空间,就会直接追加,并返回原来地址。
2,诺无法满足条件,后面无法追加足够的空间,就会在堆区重新创建一个满足追加后的大小的空间,并将原空间的字节一一复制到这个新空间,并自动free掉原空间,返回新建空间的首地址,如果realloc失败,就会返回NULL

就是说,如果realloc要的空间较大,可能会开辟一个新的空间,改变返回的地址,所以要定义新的指针来接受realloc的返回地址。

常见的动态内存开辟的错误

1,malloc开辟失败未判断

if(p==NULL)
{
	printf("%S",strerror(error));
}
else
{
	开辟成功
}

2,对动态开辟空间的越界访问
3,对非动态开辟空间的释放

int num[10];在栈区开辟的不能free
free(num);
num=NULL;

4,对同一块动态内存进行多次释放,所以要p=NULL,这样再次释放就没意义。
5,对动态空间未释放,会导致堆中满了,造成内存泄漏。
6,free了一部分动态空间,因为p的指向位置发生了改变,p不能改变。

举个例子

#include <stdio.h>
void num(char* p)
{
	p = (int*)malloc(100);
}
void test(void)
{
	char* str = NULL;
	num(str);
	strcpy(str, "abcdef");
	printf(str);
}
int main(void)
{
	test();
	return 0;
}

有形式参数,存放在栈区。
一旦函数结束,就会被销毁,无法使用。
p只是str的形参,利用p开辟空间,但不会影响str。所以str还是NULL,strcpy会造成非法访问。
但这叫,传值操作。可以通过传址操作,可以改变实参。可以使用

1,二级指针,传址调用,地址是不会销毁
2,使用return,在销毁之前,就返回了动态空间的地址。

free只会销毁堆中的空间,但地址都还在栈中,不会受影响。

柔性数组

可以人为设置数组大小的数组。
要在结构体中设置。

struct s
{
	int n;
	int arr[0];
};
sizeof(struct s)

当计算大小时,是不会计算柔性数组的大小。
除非,后面,使用malloc。

struct s* p = malloc(sizeof(struct s) + 4 * sizeof(int));

可以这样动态开辟一个空间。同时为数组开辟一个空间。

在这里插入图片描述

可以p->arr[i]访问到数组。

柔性数组的特点

1,结构体中柔性数组成员前至少有一个其他类型的成员。
2,sizeof返回结构体大小不包括柔性数组的内存大小

还有指针类型的

struct s
{
	int n;
	int* arr;
};
int main(void)
{
	struct s* p = (struct s*)malloc(sizeof(struct s));
	p->arr =(int*) malloc(10 * sizeof(int));
}

在这里插入图片描述

arr得到这个开辟的空间的首地址,同时还强转成了int*指针,这种也创建了一个数组。

在这里插入图片描述

同时还可以多次修改这个数组的大小。
每次释放内存时先
free(p->arr),要先找到这个数组空间,
再free(P)。
注意,当内存是连续的,可以提高访问效率,也有利于减少内存碎片,提高访问速度。
同时,多次malloc会增加内存碎片,降低空间使用效率。

以上就是C语言编程之动态内存与柔性数组的了解的详细内容,更多关于C语言的资料请关注脚本之家其它相关文章!

感谢阅读~

相关文章

  • c语言通过栈判断括号匹配是否配对

    c语言通过栈判断括号匹配是否配对

    前面实现了栈的基本数据结构,这里来做一个联系,用栈来解决一道比较常见的算法题,就是括号配对是否满足规则,文中有相关的代码示例供大家参考,需要的朋友可以参考下
    2023-09-09
  • C++实现LeetCode(94.二叉树的中序遍历)

    C++实现LeetCode(94.二叉树的中序遍历)

    这篇文章主要介绍了C++实现LeetCode(94.二叉树的中序遍历),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++实现简单的通讯录管理系统

    C++实现简单的通讯录管理系统

    这篇文章主要为大家详细介绍了C++实现简单的通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • c++读取数据文件到数组的实例

    c++读取数据文件到数组的实例

    今天小编就为大家分享一篇c++读取数据文件到数组的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • C语言中全局变量,局部变量,静态局部变量的区分方式

    C语言中全局变量,局部变量,静态局部变量的区分方式

    这篇文章主要介绍了C语言中全局变量,局部变量,静态局部变量的区分方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • c语言内存泄露示例解析

    c语言内存泄露示例解析

    从1988年著名的莫里斯蠕虫 攻击到有关 Flash Player 和其他关键的零售级程序的最新安全警报都与缓冲区溢出有关:“大多数计算机安全漏洞都是缓冲区溢出”,Rodney Bates 在 2004 年写道
    2013-09-09
  • C语言实战之浪漫烟花表白程序代码

    C语言实战之浪漫烟花表白程序代码

    这篇文章主要介绍了C语言实战之浪漫烟花表白程序代码,需要的朋友可以参考下
    2021-04-04
  • C++从文件中提取英文单词的实现方法

    C++从文件中提取英文单词的实现方法

    本文主要介绍了C++从文件中提取英文单词的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Qt数据库应用之实现数据的导入与导出

    Qt数据库应用之实现数据的导入与导出

    QT中涉及到数据库相关的项目,几乎都需要将少量的信息数据导出到文件保存好,然后用户可以打开该表格进行编辑,编辑完成后保存,再重新导入到软件中。所以本文将具体为大家介绍一下这一功能如何实现,感兴趣的可以跟随小编一起试一试
    2022-01-01
  • C语言实现简单通讯录

    C语言实现简单通讯录

    这篇文章主要为大家详细介绍了C语言实现简易通讯录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05

最新评论