C语言讲义——内存管理
动态分配内存
动态分配内存,在堆(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语言讲义——内存管理的更多相关文章
- JVM内存管理------JAVA语言的内存管理概述
引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...
- C语言的内存管理
C语言的内存管理 转载:http://blog.csdn.net/wind19/article/details/5964090 对于一个C语言程序而言,内存空间主要由五个部分组成代码段(.text ...
- C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针
C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针 (1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放.造成内存泄露,以下的样 ...
- R语言之内存管理
转载于:http://blog.csdn.net/hubifeng/article/details/41113789 在处理大型数据过程中,R语言的内存管理就显得十分重要,以下介绍几种常用的处理方法. ...
- JVM内存管理之JAVA语言的内存管理概述
引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...
- c语言之内存管理
在计算机系统,特别是嵌入式系统中,内存资源是非常有限的.尤其对于移动端开发者来说,硬件资源的限制使得其在程序设计中首要考虑的问题就是如何有效地管理内存资源.本文是作者在学习C语言内存管理的过程中做的一 ...
- C语言精华——内存管理,很多学校学习不到的知识~
在编写程序时,通常并不知道需要处理的数据量,或者难以评估所需处理数据量的变动程度.在这种情况下,要达到有效的资源利用--使用内存管理,必须在运行时动态地分配所需内存,并在使用完毕后尽早释放不需要的内存 ...
- C语言回顾-内存管理和指针函数
1.fgets()函数 该函数是一个文件操作相关的函数 暂时使用这个函数可以从键盘上接收一个字符串,保存到数组中 char str[50]; 1)scanf("%s",str);/ ...
- [Objective-C语言教程]内存管理(36)
内存管理是任何编程语言中最重要的过程之一.它是在需要时分配对象的内存并在不再需要时取消分配的过程. 管理对象内存是一个性能问题; 如果应用程序不释放不需要的对象,则应用程序会因内存占用增加并且性能受损 ...
随机推荐
- 如何做好智能家居工业物联网串口转WiFi/4G/以太网无线AP方案的物联网WiFi模块选型
2020年一场突如其来的灾难袭来,各大经济市场在不同程度被按下了"暂停键".物联网控制作为新兴行业优势凸显出来,其无接触式的交互方式,远程控制,智能控制车间,给人民带来安全.智能的 ...
- 给Swagger换一套皮肤 Knife4j集成记录
Swagger有一套经典的UI,但是并不是很好用,之前有看到Knife4j,界面没管.功能完善,因此尝试集成. demo参考示例地址:knife4j-spring-boot-demo Knife4j前 ...
- shell脚本之字符串测试表达式
1.字符串测试操作符 字符串测试操作符的作用有:比较两个字符串是否相同.字符串的长度是否为零,字符串是否为NULL(注:bash区分零长度字符串和空字符串等) 下表为常用字符串操作符 也可以通过man ...
- pause容器作用
1.概念 Pause容器 全称infrastucture container(又叫infra)基础容器. 作为init pod存在,其他pod都会从pause 容器中fork出来. 每个Pod里运行着 ...
- pandas神器操作excel表格大全(数据分析数据预处理)
使用pandas库操作excel,csv表格操作大全 关注公众号"轻松学编程"了解更多,文末有公众号二维码,可以扫码关注哦. 前言 准备三份csv表格做演示: 成绩表.csv su ...
- Django实现文件上传功能
文件上传 关注公众号"轻松学编程"了解更多. 1.创建上传文件夹 在static文件夹下创建uploads用于存储接收上传的文件 在settings中配置,MEDIA_ROOT=o ...
- Hadoop高可用
一.原因 - NameNode是HDFS的黑心配置HDFS有事hadoop的核心组件 NameNode 在Hadoop及群众至关重要 - NameNode的宕机导致集群的不可用 二.解决方案 其中 N ...
- 10万用户一年365天的登录情况如何用redis存储,并快速检索任意时间窗内的活跃用户
1.redsi的bitmap数据结构介绍 bitmap本质上是一个string类型,只是他操作的是string的某个位是0还是1. setbit和getbit 两条命令是对字符串的位操作.每个位只能是 ...
- c#集合随机数
List<int> list = new List<int>(10); Random r=new Random(); int num = 0; for (int i = 0; ...
- 配置交换机基于接口划分VLAN(接入层设备作为网关)
组网图形 简介 划分VLAN的方式有:基于接口.基于MAC地址.基于IP子网.基于协议.基于策略(MAC地址.IP地址.接口).其中基于接口划分VLAN,是最简单,最常见的划分方式. 基于接口划分VL ...