【C语言】内存管理(malloc, calloc, realloc, free),补充:perror和fprintf的区别

本文主要是介绍【C语言】内存管理(malloc, calloc, realloc, free),补充:perror和fprintf的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【C语言】内存通过指针来管理。指针变量存储内存地址,这个内存地址可以指向任何类型的变量。

指针变量声明:基类型 *指针变量名;

获取变量的内存地址:&变量;

指针指向变量的内存地址:指针变量名=&变量;

获取指针指向的内存地址的值:*指针变量名;

内存管理的函数:malloc, calloc, realloc, free均是标准库stdlib.h中的函数。

malloc:动态分配内存空间,堆区分配指定大小的内存用于存放数据,值不会被初始化。

calloc:动态分配内存空间,空间大小可定制,每个字节的值都初始化为0。

realloc:重新分配内存,原来的内存块重新扩展到新的大小,可能新的内存地址。

free:释放由malloc, calloc, realloc分配的内存空间。释放后该内存可分配给其它用途。

void free(void *ptr);

注:参数ptr是指向已分配内存块的指针。

       不返回任何值。

1、malloc, free

void *malloc(size_t size);

注:参数size是size_t类型(无符号整型)的值,即需要分配的内存块的大小(单位:字节)。

       返回void类型的指针,指向分配的内存块。若分配失败,返回NULL。

#include <stdio.h>
#include <stdlib.h>int main(void)
{int *numbers;      // 声明指针变量numbers = (int *)malloc(5 * sizeof(int));        // 分配内存空间// 判断内存分配是否成功,若失败,则打印错误信息并退出程序if(numbers == NULL){perror("Memory alloation failed");return 1;}// 使用分配的内存空间for(int i = 0;i < 5;i++){numbers[i] = i + 1;}// 输出分配的内存内容for(int i = 0;i < 5;i++)   {printf("\"numbers\", data %d is %d\n",i , numbers[i]);}// 释放分配的内存空间,避免内存泄漏free(numbers); // 指针设为NULL,避免指针悬空(野指针)numbers = NULL;return 0;
}// 结果:
"numbers", data 0 is 1
"numbers", data 1 is 2
"numbers", data 2 is 3
"numbers", data 3 is 4
"numbers", data 4 is 5

2、calloc, free

void *calloc(size_t num, size_t size);

注:参数num是需要被分配的元素个数。参数size是每个元素的大小(单位:字节)。

       返回void类型的指针,指向分配的内存块。若分配失败,返回NULL.

       每个字节的初始化的值为0。

#include <stdio.h>
#include <stdlib.h>int main(void)
{    char *strings;strings = (char *)calloc(6, sizeof(char));    // 分配内存空间,6个字符大小的内存空间,初始值都为0// 判断内存分配是否成功,若失败,则打印错误信息并退出程序if(strings == NULL){fprintf(stderr, "Memory allocation failed");return 1;}// 打印初始值for(int i = 0;i < 6;i++){printf("Before: strings=%s, data %i is %d\n", strings, i, strings[i]);}// 使用分配的内存空间for(int i = 0;i < 6;i++){strings[i] = (char) (65 + i);     // ASCII码中:65-A}// 输出分配的内存内容for(int i = 0;i < 6;i++){printf("After: strings=%s, data %i is %c\n", strings, i, strings[i]);}// 释放分配的内存空间,避免内存泄漏free(strings);// 指针设为NULL,避免指针悬空(野指针)strings = NULL;return 0;
}// 结果为:
Before: strings=, data 0 is 0
Before: strings=, data 1 is 0
Before: strings=, data 2 is 0
Before: strings=, data 3 is 0
Before: strings=, data 4 is 0
Before: strings=, data 5 is 0
After: strings=ABCDEF, data 0 is A
After: strings=ABCDEF, data 1 is B
After: strings=ABCDEF, data 2 is C
After: strings=ABCDEF, data 3 is D
After: strings=ABCDEF, data 4 is E
After: strings=ABCDEF, data 5 is F

3、realloc, free

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

注:参数ptr是指向原分配内存块的指针。参数newsize是新的内存块大小(单位:字节)。

       返回void类型的指针,指向重新分配后的内存块。若重新分配失败,返回NULL;原内存块仍有效,不会被释放。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(void)
{char *s;s = (char *)malloc(5 * sizeof(char));      // 分配内存空间// 判断内存分配是否成功,若失败,则打印错误信息并退出程序if(s == NULL){perror("Memory allocation failed");return 1;}else{strcpy(s, "hello");     // 使用分配的内存空间, strcpy:复制字符串}// 输出分配的内存内容for(int i = 0; i < 5 ;i++){printf("s=%s, data %d is %c\n", s, i, s[i]);}printf("\n");// 重新分配内存空间,增加5个字符的空间(共10个字符)s = (char *)realloc(s, 10 * sizeof(char));if(s == NULL){perror("Memory allocation failed");free(s);                // 释放原来的内存空间return 1;}// 使用重新分配的内存空间, strcat:字符串末尾追加内容strcat(s, "world");// 输出重新分配的内存内容for(int i = 0; i < 10 ;i++){printf("s=%s, data %d is %c\n", s, i, s[i]);}// 释放分配的内存空间,避免内存泄漏free(s);// 指针设为NULL,避免指针悬空(野指针)s = NULL;return 0;
}// 结果为:
s=hello, data 0 is h
s=hello, data 1 is e
s=hello, data 2 is l
s=hello, data 3 is l
s=hello, data 4 is os=helloworld, data 0 is h
s=helloworld, data 1 is e
s=helloworld, data 2 is l
s=helloworld, data 3 is l
s=helloworld, data 4 is o
s=helloworld, data 5 is w
s=helloworld, data 6 is o
s=helloworld, data 7 is r
s=helloworld, data 8 is l
s=helloworld, data 9 is d

补充:perror和fprintf的区别:

perrorfprintf
void perror(const char *str)int fprintf(FILE *stream, const char *format,...)
提供前缀字符串(自定义信息,在系统定义的错误信息之前)提供格式
输出错误信息格式化输出
输出到stderr

可以标准输出stdout,

也可以输出到指定文件

自动包含系统定义的错误描述构建错误信息
不返回任何值若成功,返回写入的字符总数,否则返回-1

这篇关于【C语言】内存管理(malloc, calloc, realloc, free),补充:perror和fprintf的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/847319

相关文章

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的

SpringBoot使用minio进行文件管理的流程步骤

《SpringBoot使用minio进行文件管理的流程步骤》MinIO是一个高性能的对象存储系统,兼容AmazonS3API,该软件设计用于处理非结构化数据,如图片、视频、日志文件以及备份数据等,本文... 目录一、拉取minio镜像二、创建配置文件和上传文件的目录三、启动容器四、浏览器登录 minio五、

C语言线程池的常见实现方式详解

《C语言线程池的常见实现方式详解》本文介绍了如何使用C语言实现一个基本的线程池,线程池的实现包括工作线程、任务队列、任务调度、线程池的初始化、任务添加、销毁等步骤,感兴趣的朋友跟随小编一起看看吧... 目录1. 线程池的基本结构2. 线程池的实现步骤3. 线程池的核心数据结构4. 线程池的详细实现4.1 初

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

IDEA中的Kafka管理神器详解

《IDEA中的Kafka管理神器详解》这款基于IDEA插件实现的Kafka管理工具,能够在本地IDE环境中直接运行,简化了设置流程,为开发者提供了更加紧密集成、高效且直观的Kafka操作体验... 目录免安装:IDEA中的Kafka管理神器!简介安装必要的插件创建 Kafka 连接第一步:创建连接第二步:选

python中json.dumps和json.dump区别

《python中json.dumps和json.dump区别》json.dumps将Python对象序列化为JSON字符串,json.dump直接将Python对象序列化写入文件,本文就来介绍一下两个... 目录1、json.dumps和json.dump的区别2、使用 json.dumps() 然后写入文

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖