声明数组时,必须指定数组长度,才可以编译,但是如果需要在运行时,指定数组的长度的话,那么就需要动态的分配内存。

C函数库stdlib.h提供了两个函数,malloc和free,分别用于执行动态内存分配和释放,这些函数维护一个可用的内存池,当程序需要内存时,它就调用malloc从内存池中提取一块合适的内存,并向该程序返回一个指向这块内存的指针,这块内存没有以任何方式进行初始化。如果需要初始化,可用使用calloc函数。当一块分配的内存不再使用时,程序应该调用free函数把它归还给内存池。

void *malloc(size_t  size);
void free(void *pointer);

当malloc申请内存失败时,返回的是NULL指针,所以需要对malloc返回值进行检查,确保非NULL。而free的参数,要么是NULL,要么是malloc,calloc或者realloc返回的值。向free传入NULL,不会产生任何效果。

malloc返回的是void *类型的指针,所以有的编译器可能在使用之前,需要行类型转换。

char *sPtr;
//类型转换一下
sPtr = (char *)malloc(12);
strcpy(sPtr, "yangxunwu");

calloc,也是分配内存,不过在分配之前会把内存初始化为0,而malloc不会初始化

void *calloc(size_t num_elements, size_t element_size);

calloc还有一个区别是它的参数包含元素的个数,以及单个元素的字节数。

realloc用于修改一个原先以及分配内存块的大小,使用这个函数可以是一块内存扩大或者缩小,如果原先的大小可以改变,那么将直接在内存块进行操作,如果无法改变,那么realloc将重新分配正确大小的内存,并把原先的内存内容复制到新的块上。

void * realloc(void *ptr, size_t new_size);

在使用realloc后就不可以使用指向旧内存的指针,而是应该改用realloc所返回的指针。

#include <stdio.h>
#include <stdlib.h> int main()
{
char *sPtr;
char *nPtr;
//类型转换一下
sPtr = malloc(12);
strcpy(sPtr, "yangxunwu");
printf("%s\n", sPtr); //使用新的指向内存的指针
nPtr = realloc(sPtr, 20);
printf("%s\n", nPtr); return 0;
}

如果realloc的第一个参数为空,那么就和malloc一样。

当内存分配使用后不需要使用时可以使用free函数释放内存到内存池中,如果malloc或者realloc或者calloc失败返回的是NULL,所以对NULL进行指针解引用会报错,或者返回指针后,操作超过了边界free释放非动态分配的内存,或者部分动态分配的内存都是错误的。如果内存已经释放,在访问是错误的,或者只申请内存不释放,会导致内存泄露。

C和指针 第十一章 动态内存分配的更多相关文章

  1. 《C和指针》 读书笔记 -- 第11章 动态内存分配

    1.C函数库提供了两个函数,malloc和free,分别用于执行动态内存分配和释放,这些函数维护一个可用内存池. void *malloc(size_t size);//返回指向分配的内存块起始位置的 ...

  2. C++学习笔记(十一):void*指针、类型转换和动态内存分配

    void*指针 void关键字表示“空类型”的概念.但是,这里的“空类型”不表示“任意类型”,而是表示不存在的意思,也就是说C/C++不允许你写语句void a,不存在类型为void的东西. void ...

  3. C和C指针小记(十六)-动态内存分配

    动态内存分配 1.1 为什么使用动态内存分配 直接声明数组的方式的缺点: 1) 声明数组必须指定长度限制.无法处理超过声明长度的数组. 2) 如果声明更大的常量来弥补第一个缺点,会造成更多的内存浪费. ...

  4. <c和指针>学习笔记5动态内存分配和预处理器

    1 动态内存 比如声明数组得时候,我们需要提前预估数组长度,分配大了浪费,少了就更不好操作了.从而引入动态分配,需要的时候再分配. (1)malloc和free void *malloc(size_t ...

  5. C++ Primer 5th 第12章 动态内存

    练习12.1:在此代码的结尾,b1 和 b2 各包含多少个元素? StrBlob b1; { StrBlob b2 = {"a", "an", "th ...

  6. 【STM32H7教程】第27章 STM32H7的TCM,SRAM等五块内存的动态内存分配实现

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第27章       STM32H7的TCM,SRAM等五块内 ...

  7. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  8. C++指针和动态内存分配

    指针和动态内存分配 数组与指针 数组 数组名是一个指针常量. 数组名传递数据时,传递的是地址. 数组作为函数参数时不指定第一维大小. 对象数组 A a[2] = {A(1,2)}; 执行时先调用有参数 ...

  9. C++ Primer : 第十二章 : 动态内存之动态内存管理(new和delete)

    C++语言定义了两个运算符来分配和释放动态内存:运算符new分配内存,运算符delete释放new分配的内存. 运算符new和delete 使用new动态分配和初始化对象 在自由空间分配的内存是无名的 ...

随机推荐

  1. codev 2147 数星星

    2147 数星星 http://codevs.cn/problem/2147/ 题目描述 Description 小明是一名天文爱好者,他喜欢晚上看星星.这天,他从淘宝上买下来了一个高级望远镜.他十分 ...

  2. SQL Server日志文件(LDF文件)

    一.日志文件过大处理方法: 1.设置数据库模式为简单模式:ALTER DATABASE 数据库名 SET RECOVERY SIMPLE 或者选中数据库-属性-选项-恢复模式设置为简单. 2.收缩日志 ...

  3. 熟悉MyEclipse

    资源网址:http://www.myeclipsecn.com/learningcenter/ 20151126 [从这里开始]量身打造自己的MyEclipse(多图) 主要讲在MyEclipse里面 ...

  4. rpc框架之 thrift连接池实现

    接前一篇rpc框架之HA/负载均衡构架设计 继续,写了一个简单的thrift 连接池: 先做点准备工作: package yjmyzz; public class ServerInfo { publi ...

  5. js动态创建style节点(js文件中添加css)

    ie6 不能 document.createElement('style') 然后append到head标签里.所以就找到这样个好文章 --------------------- 有很多提供动态创建 ...

  6. VS 报cmath(19): error C2061: 语法错误: 标识符“acosf” 错误

    这是因为我在.c文件中用了 #include <iostream> using namespace std; 这样编译的时候就报: 出现错误类型如下:1>c:\program fil ...

  7. bzoj1800[Ahoi2009]fly 飞行棋 暴力枚举

    找了道bzoj的水题,千年难得一遇. 建议初学者做做,然而我个蒟蒻初学时应该A不了..... < http://www.lydsy.com/JudgeOnline/problem.php?id= ...

  8. win7/8 访问 访问局域网 默认加载域 而无法成功访问的问题

    运行 gpedit.msc选择 本地计算机策略- 计算机配置-windows设置-安全设置-本地策略-安全选项 其中有个 网络安全:lan管理员身份验证级别 选择 发送LM和NTLM响应

  9. JavaScript类库---JQuery(一)

    1.基础: Jquery类库定义了一个全局函数:JQuery(); 别名$.是JQuery在全局命名空间中定义的唯一两个变量.返回一个新创建的JQuery对象: 另:JQuery中定义的许多方法返回值 ...

  10. 随便写一下看下效果。一个js问题

    (function(a){ console.log(a); var a = 10; function a(){} }(100)); 问:执行这段代码会输出什么.