C语言动态分配内存,malloc的出现就是来弥补静态内存分配的缺点

比如说我们在定义数组的时候,数组的长度必须是一个常量,不能改变的值,假如我事先定义了数组,一旦业务需求发生改变,那么这个数组就不能再使用了。

传统的数组定义也就是静态分配,是不能够手动释放的,只能等待系统释放,静态分配的内存,是分配在栈中的,C语言中的函数调用也是通过栈来实现的,栈有一个特点就是先进后出,在调用函数的时候,是先压入栈,然后从最上面的函数开始执行

我们先来看看内存四区,分别为堆区,栈区,数据区,代码区,对于这四个区,做了以下总结

代码区:
  程序执行二进制码(程序指令)
  共享,只读
数据区 :
  初始化数据区(data)
  未初始化数据区(bss)
  常量区
栈区 :
  系统为每一个程序分配一个临时的空间,
  局部变量,函数信息,函数参数,数组
  栈区大小为:1M
  在windows中可以扩展到10M
  在linux中可以扩展到16M
堆区 :
  存储大数据,图片,音乐,视频
  手动开辟 malloc
  手动释放           free

栈区大小为:1M,我们来验证一下

int zhan[] = {  };

在C语言中,我们定义了一个数组,长度为820000,那么我们知道,在栈中我们最多可分配1M的内存,我们可以计算一下,这八百二十万的长度占了多大的内存,

定义的是int类型,所以8200000*4=32800000(字节)

得到的结果再除以1024,32800000/1024=32031.25(KB)

得到的结果再除以1024,32031.25/1024=31.280517578125(M)

大约是31M,最终运行起来,这个程序是会报错的。

接下来我们就开辟堆内存存储数据,这就用到了函数malloc

动态分配内存函数

malloc

使用函数之前我们要引用头文件stdlib.h

#include<stdlib.h>

malloc函数语法示例

int* p1 = (int*)malloc(sizeof(int))

返回值类型为void* 类型,也就是指针类型,int* p1代表一个以int类型地址为内容的指针变量

int类型在内存中占用的大小为 4字节。

malloc括号中就是你要开辟的空间大小,单位是字节,分配一块连续的区域

假如我要开辟一个空间,里面存储5个数字,那么代码如下

int* p1 = (int*)malloc(sizeof(int)*);

这样的格式可以更容易的理解,当然你也可以像下面这么写

int* p1 = (int*)malloc();

如果地址开辟成功,返回一个内存地址,否则返回NULL,需要注意的是,如果开辟失败了,那么在后边的程序中调用,程序就会报错,所以有时候还要加一个判断条件,这点要注意

if (p1 == NULL) {
printf("程序异常");
return -;
}

成功以后,我们可以使用这个内存空间,对它进行赋值。

在使用完之后,也可以调用free函数释放,代码如下

free(p1);

那么,当我们释放这个p1之后,这个内存空间还能调用吗?其实还可以调用的。在释放之后,这个内存地址就变成了一个野指针,还可以进行赋值

为了避免野指针,在free(p1)后在加上一段代码

p1 = NULL;

赋值为NULL,这个是可有可无的。

我们再来看一个函数,叫做内存操作函数

memset(),memcpy(),memmove(),

引用 string.h

#include<string.h>

1.memset()参数,  void *memset(void *s, intc, size_tn);

我们来看看它的示例

int* p = (int*)malloc(sizeof(int) * );
memset(p, , );

传入p这个内存地址,重置为0,字节为40字节

它在重置为0时有效,并不是真正意义上的重置

这个函数作用通常是一串连续的内存一起操作,不会单独对变量进行操作。

2.memcpy(),参数,void *memcpy(void *dest, constvoid *src, size_tn);

示例:

   int arr[] = { ,,,,,,,, };
int* p = (int*)malloc(sizeof(int) * );
memcpy(p, arr, sizeof(int) * );

arr存在栈内存中,p存在堆内存中,我们现在要把arr中的数复制到p中,这就用到了  memcpy()函数

用法:

memcpy(新数据,源数据,内存大小(字节))

它不同于strcpy()这个函数,strcpy()是字符串拷贝遇到\0会停止,而memcpy()拷贝的是内存,拷贝的内容和字节有关。

如果参数1和参数2的内存地址重叠,可能会导致程序报错,应尽量避免

3.memmove()

memmove()功能用法和memcpy()一样,区别在于:dest和src所指的内存空间重叠时,memmove()仍然能处理,不过执行效率比memcpy()低些。

4.memcmp(),参数,int memcmp(constvoid *s1, constvoid *s2, size_tn);

    int arr[] = { ,,,,,,,, };
int arry[] = { ,,,, };
int value = memcmp(arr, arry, );

第一个参数和第二个参数进行比较,比较前20个字节,也就是前5个数,如果相等返回0,否则返回-1;

同样可以比较字符串,代码如下:

    char arr[] = "hello\0 word";
char arry[] = "hello\0 word";
int value = memcmp(arr, arry, );

C语言中堆内存的开辟和释放与内存处理函数的更多相关文章

  1. C语言中堆和栈的区别

    原文:http://blog.csdn.net/tigerjibo/article/details/7423728 C语言中堆和栈的区别 一.前言: C语言程序经过编译连接后形成编译.连接后形成的二进 ...

  2. linux内存优化之手工释放linux内存

    先介绍下free命令 Linux free命令用于显示内存状态. free指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存区段,以及系统核心使用的缓冲区等. 语法: free [- ...

  3. C语言中所有变量和常量所使用的内存总结

    (1)相同点:三种获取内存的方法,都可以给程序提供可用内存,都可以用来定义变量给程序用.(2)不同点:栈内存对应C中的普通局部变量(别的变量还用不了栈,而且栈是自动的,由编译器和运行时环境共同来提供服 ...

  4. c语言中结构体的定义、初始化及内存分配

    #include <stdio.h> struct person { char *name; int age; }; int main() { //结构体可以定义在函数内,也可以定义到函数 ...

  5. C语言中字符型,整数型,浮点型在内存中如何存储

    ···void main() { unsigned char a = 97; printf("%p",&a); printf("%c,%d\n", a, ...

  6. c语言中通过指针将数值赋值到制定内存地址

    1.一种直观的方法 假设现在需要往内存0x12ff7c地址上存入一个整型数0x100.我们怎么才能做到呢? 我们知道可以通过一个指针向其指向的内存地址写入数据,那么这里的内存地址0x12ff7c其本质 ...

  7. C 语言中可以调用命令行指令的 system()函数

    C语言有一个system函数(在<stdlib.h>头中,C++则为<cstdlib>头),可以用来调用终端命令.原型如下: int system(const char *cm ...

  8. C语言中动态内存分配的本质是什么?

    摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...

  9. C语言中内存的管理

    一.动态内存分配与释放 1.为什么要使用动态内存分配,以下看一个实例,关于超市中购买记录的一段程序 #include <stdio.h> #include <string.h> ...

随机推荐

  1. org.springframework.data.redis.cache.RedisCacheManager

    org.springframework.data.redis.cache.RedisCacheManager

  2. leetCode题解之Jewels and Stones

    1.题目描述 2.分析 使用HashTable 是解决这种的好方法. 3.代码 int numJewelsInStones(string J, string S) { map<char,int& ...

  3. Jquery Ajax 提交json数据

    在MVC控制器(这里是TestController)下有一个CreateOrder的Action方法 [HttpPost] public ActionResult CreateOrder(List&l ...

  4. 选中复选框,才能在文本框中输东西。button按钮已启用,

  5. 一些centos 6和centos 7的区别

      CentOS 6(OLE 6,RHEL 6类似) CcnetOS 7(OLE 7,RHEL 7类似) 影响 默认文件系统 ext4 xfs 大量小文件在ext4上工作性能较好在64位linux中, ...

  6. Linode VPS主机套餐方案降低处理方法且不影响数据

    使用Linode VPS主机产品经历过512MB内存升级至1GB内存,再升级至2GB内存,以及目前推出1GB内存方案月付10美元.比如我们在使用Linode 2GB内存方案的时候占用资源不是太多,其实 ...

  7. (z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!

    摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文 名“GPU编程与CG语言之阳春白雪下里巴人” BRDF 光照模型 10.2.1 什么 ...

  8. 浅谈 JSONP

    说起跨域的解决方案,总是会说到 JSONP,但是很多时候都没有仔细去了解过 JSONP,可能是因为现在 JSONP 用的不是很多(多数时候都是配置响应头实现跨域),也可能是因为用 JSONP 的场景一 ...

  9. python第四课——运算符

    一.python中的运算符: 什么是运算符? 就是计算机语言中用来参与运算的符号!! 1.算数运算符: 符号:+ - * / %(取余,取模) //(取整) **(开方) 2.比较运算符: 特点:比较 ...

  10. centos6.2/6.3/6.4+nginx+mysql5.5+php5.3.14

    一.安装所需软件包yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype free ...