动态分配内存

动态分配内存,在堆(heap)中分配。

void *malloc(unsigned int num_bytes);
  • 头文件 stdlib.h或malloc.h
  • 向系统申请分配size个字节的内存空间
  • 返回void* 类型(未确定类型的指针)
  • 可强制转换为任何类型的指针
void *memset(void *s,int c,size_t n)
  • 头文件 string.h或memory.h
  • 将内存空间s的前n个字节的值设为值c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void getResult(char *pp) {
pp = (char *)malloc(10);
memset(pp, 0, 10);
strcpy(pp, "函数内");
}
void testMalloc() {
char *p = NULL;
getResult(p);
printf("getResult()后:%s\n", p); p = (char *)malloc(10);
memset(p, 0, 10);
strcpy(p, "调用方");
printf("%s\n", p);
} int main(int argc, char *argv[]) {
testMalloc();
return 0;
}

二级指针

二级指针——指向指针的指针

如果要在函数中申请内存,调用放还想得到申请的新内存的话,需要使用二级指针:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int g_size = 20; //申请新的内存空间
void _exploit(char **pp) {
*pp = (char *)malloc(g_size);
memset(*pp, 0, g_size);
strcpy(*pp, "函数内的新空间");
} //释放内存空间
void _giveBack(char **pp) {
if (*pp != NULL) {
free(*pp);
*pp = NULL;
}
} main() {
char *p = NULL;
_exploit( &p );
printf("【%s】\n", p);
_giveBack(&p);
printf("【%s】\n", p); p = (char *)malloc(g_size);
memset(p, 0, g_size);
strcpy(p, "调用方的新空间");
printf("【%s】\n", p);
_giveBack(&p);
printf("【%s】\n", p);//不加【】不打印(null),加了才打印
}

lloc系列函数

malloc 动态分配内存,需要与memset配合使用
calloc 动态分配完内存后,自动初始化内存空间为零
realloc 为数组重新分配内存
#include<stdio.h>
#include<stdlib.h>
main() {
char *p = NULL;
printf("p:%s\n", p);
p = (char *)malloc(10);
printf("p:%s\n", p);
if (p!=NULL) {
free(p);
p=NULL;
}
p = (char *)calloc(10,sizeof(char));
printf("p:%s\n", p);
if (p!=NULL) {
free(p);
p=NULL;
}
printf("p:%s\n", p);
}
#include <stdio.h>
main() {
char arr[3];
int n = 1;
int i = 1;
printf("n = %d\n", n);
char *p = &arr[0];
char *p2 = realloc(p, 10);
for(i = 0; i<10; i++) {
arr[i] = 9;
}
printf("n = %d\n", n);
}

释放内存

  • malloc等内存分配函数开辟的内存来自于堆(heap),
  • 堆是有限的,不能只开辟,不释放,
  • 使用free函数释放不使用的内存。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void testMalloc() {
char *p = (char *)malloc(10);
memset(p, 0, 10);
strcpy(p, "调用方");
printf("p:%s\n", p);
if(p != NULL) {
free(p);
p = NULL;
}
printf("p:%s\n", p);
} int main(int argc, char *argv[]) {
testMalloc();
return 0;
}

示例:猜价格

知识点:

  • 内存管理
  • 二级指针
  • 循环
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int getResult(int n, char **pp) {
int nRealPrice = 2999;
*pp = (char *)malloc(10);
memset(*pp, 0, 10);
if (n > nRealPrice) {
strcpy(*pp, "高了");
return 0;
} else if (n < nRealPrice) {
strcpy(*pp, "低了");
return 0;
} else {
strcpy(*pp, "正确");
return 1;
}
} void setFree(char **pp) {
if(*pp != NULL) {
free(*pp);
*pp = NULL;
}
} void guessPrice() {
int n = 0;
char *p = NULL;
int nRet = 0; do {
scanf("%d", &n);
nRet = getResult(n, &p);
printf("p:%s\n", p); setFree(&p);
printf("p:%s\n", p);
} while(nRet == 0 );
}
int main(int argc, char *argv[]) {
guessPrice();
return 0;
}

模拟Java的ArrayList的add()方法

ArrayList又叫动态数组,长度不够的时候可以自动申请新的内存。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int capacity = 3;
static int index = 0;
void foreach(char * p) {
puts("");
for(int i = 0; i<=index; i++) {
printf("%c ", *(p+i));
}
puts("");
}
void add(char **p, char c) {
if (*p == NULL) {
*p = (char*)calloc(capacity, sizeof(char));
} else {
if(index >= capacity ) {
capacity += (capacity>>1);
printf("新容量:%d \n", capacity);
char *p2 = (char*)realloc(*p, capacity);
//free(*p);
*p = p2;
}
}
*(*p+index) = c;
index++;
//printf("index = %d \n",index);
}
main() {
char* p = NULL;
int n = 1000;
for(int i = 0; i<20; i++) {
add(&p, 'A');
foreach(p);
}
printf("int = %d \n", n);
}

C语言讲义——内存管理的更多相关文章

  1. JVM内存管理------JAVA语言的内存管理概述

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...

  2. C语言的内存管理

    C语言的内存管理 转载:http://blog.csdn.net/wind19/article/details/5964090   对于一个C语言程序而言,内存空间主要由五个部分组成代码段(.text ...

  3. C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针

    C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针 (1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放.造成内存泄露,以下的样 ...

  4. R语言之内存管理

    转载于:http://blog.csdn.net/hubifeng/article/details/41113789 在处理大型数据过程中,R语言的内存管理就显得十分重要,以下介绍几种常用的处理方法. ...

  5. JVM内存管理之JAVA语言的内存管理概述

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...

  6. c语言之内存管理

    在计算机系统,特别是嵌入式系统中,内存资源是非常有限的.尤其对于移动端开发者来说,硬件资源的限制使得其在程序设计中首要考虑的问题就是如何有效地管理内存资源.本文是作者在学习C语言内存管理的过程中做的一 ...

  7. C语言精华——内存管理,很多学校学习不到的知识~

    在编写程序时,通常并不知道需要处理的数据量,或者难以评估所需处理数据量的变动程度.在这种情况下,要达到有效的资源利用--使用内存管理,必须在运行时动态地分配所需内存,并在使用完毕后尽早释放不需要的内存 ...

  8. C语言回顾-内存管理和指针函数

    1.fgets()函数 该函数是一个文件操作相关的函数 暂时使用这个函数可以从键盘上接收一个字符串,保存到数组中 char str[50]; 1)scanf("%s",str);/ ...

  9. [Objective-C语言教程]内存管理(36)

    内存管理是任何编程语言中最重要的过程之一.它是在需要时分配对象的内存并在不再需要时取消分配的过程. 管理对象内存是一个性能问题; 如果应用程序不释放不需要的对象,则应用程序会因内存占用增加并且性能受损 ...

随机推荐

  1. B. Petya and Divisors 解析(思維)

    Codeforce 111 B. Petya and Divisors 解析(思維) 今天我們來看看CF111B 題目連結 題目 略,請看原題 前言 看了別人的解答就豁然開朗 @copyright p ...

  2. 4g数据无线传输终端dtu

    将串口数据转换为IP数据或将IP数据转换为串口数据并且进行传输的过程被称为数据透明传输,利用4G网络进行数据透明传输的设备被称为4G网络无线数据双向透明传输终端,也可以称为4G DTU,现在市面上大多 ...

  3. 修改redo log 的大小

    alert日志中含有大量警告信息:"Thread 1 cannot allocate new log, sequence 320xx Checkpoint not complete" ...

  4. 转载-Eclipse无法打开Eclipse MarketPlace的解决办法

    问题描述: Eclipse点击 help-->Eclipse MarketPlace 后无任何反应,无报错,打不开 解决方法: 重新安装一下 epp MarketPlace help--> ...

  5. z-index属性详解

    z-index属性详解 目录 z-index属性详解 一.定义和用法 二.代码 三.效果图 一.定义和用法 z-index属性指定一个元素的堆叠顺序,也就是z轴 position属性定义的是x轴和y轴 ...

  6. 教你写个简单到的 Redis Client 框架 - .NET Core

    目录 1,关于 Redis RESP 定义数据类型 2,定义异步消息状态机 3,定义命令发送模板 4,定义 Redis Client 5,实现简单的 RESP 解析 6,实现命令发送客户端 7,如何使 ...

  7. CSS三大特性及权重叠加

    层叠性: 1.样式冲突,遵循的原则是就近原则,哪个样式离结构近,就执行哪个样式 2.样式不冲突,不会层叠 继承性: 子标签会继承父标签的某些样式,如文本颜色和字号 优先级: 当同一个元素指定多个选择器 ...

  8. 【java】校验当前时间是否在规定的时间内

    废话不多说直接贴代码. 我的日期格式是 8:00-22:00 要用的自己换下格式哈. public class CheckClosingTimeUtil { /** * 校验当前时间是否在规定时间内 ...

  9. maven pom.xml 报错

    首先介绍背景,在eclipse中导入一个maven的项目,在我之前的电脑上导入好用,在自己的电脑上导入居然pom报错了Missing artifact junit:junit:jar:4.11,还会有 ...

  10. 读取由FileProvider创建的Uri路径文件

    val uri = intent.clipData.getItemAt(0).uri //读取由FileProvider传递的uri文件val fileDecript= contentResolver ...