C语言中如何动态分配内存并进行操作

C语言文章更新目录

C语言学习资源汇总,史上最全面总结,没有之一
C/C++学习资源(百度云盘链接)
计算机二级资料(过级专用)
C语言学习路线(从入门到实战)
编写C语言程序的7个步骤和编程机制
C语言基础-第一个C程序
C语言基础-简单程序分析
VS2019编写简单的C程序示例
简单示例,VS2019调试C语言程序
C语言基础-基本算法
C语言基础-数据类型
C语言中的输入输出函数
C语言流程控制语句
C语言数组——一维数组
C语言数组——二维数组
C语言数组——字符数组
C语言中常用的6个字符串处理函数
精心收集了60个C语言项目源码,分享给大家
C语言核心技术——函数
C代码是怎样跑起来的?
C语言实现字符串的加密和解密
C语言——文件的基本操作
使用C语言链表创建学生信息并且将信息打印输出
图解C语言冒泡排序算法,含代码分析
实例分析C语言中strlen和sizeof的区别
开发C语言的3款神器,VS2019、VScode和IntelliJ Clion
动图图解C语言选择排序算法,含代码分析
动图图解C语言插入排序算法,含代码分析
C语言指针数组和数组指针详解
5分钟搞懂C语言中的传值和传址
C语言——动态数组的创建和使用
C语言中#include<…>和#include“…“的区别
2024年C语言最新经典面试题汇总(1-10)
2024年C语言最新经典面试题汇总(11-20)

C语言实例专栏(持续更新中…)

C语言中允许程序在运行时创建和释放内存,以适应程序数据结构的大小变化或其他不确定的内存需求。也就是常说的动态内存分配。
这篇文章将详细介绍动态分配内存并进行操作的基本步骤以及注意事项。
在这里插入图片描述

动态内存分配的函数

1. malloc()

用于分配指定大小的内存块。其函数原型如下:

void *malloc(size_t size);

malloc() 接受一个参数 size,表示需要分配的字节数。如果内存分配成功,它返回一个指向已分配内存区域的指针;否则,若无法分配足够的内存,返回 NULL

2. calloc()

malloc() 类似,但额外提供了分配内存并将其所有字节初始化为零的功能。其函数原型如下:

void *calloc(size_t num, size_t size);

calloc() 接收两个参数:num 表示元素数量,size 表示每个元素的大小。它为 num 个大小为 size 的元素分配内存,并清零。返回值与 malloc() 相同。

3. realloc()

用于调整已分配内存块的大小。其函数原型如下:

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

realloc() 接收两个参数:ptr 是先前通过 malloc()calloc()realloc() 分配的内存区域的指针,size 是新的所需大小。它尝试调整指定内存块的大小,如果必要,可能会移动内存块到另一个位置。返回值为调整后内存块的新地址(可能与原地址相同或不同),若分配失败,则返回 NULL,此时原始内存块保持不变。

4. free()

用于释放之前动态分配的内存。其函数原型如下:

void free(void *ptr);

free() 接收一个参数 ptr,即之前由内存分配函数返回并不再使用的内存区域的指针。调用 free() 后,该内存区域被释放,可供后续分配使用。

动态内存分配的操作步骤

分配内存:

// 分配一个整数数组,包含10个元素
int *dynamicArray = (int*)malloc(sizeof(int) * 10);

// 或者使用calloc,同时初始化为零
int *zeroInitializedArray = (int*)calloc(10, sizeof(int));

使用分配的内存:

// 填充动态数组
for (int i = 0; i < 10; ++i) {
    dynamicArray[i] = i * i;
}

// 访问和操作动态分配的数据
printf("Element at index 5: %d\n", dynamicArray[5]);

调整内存大小(如果需要):

// 假设需要增加数组容量至20个元素
int *temp = (int*)realloc(dynamicArray, sizeof(int) * 20);
if (temp != NULL) {
    dynamicArray = temp; // 更新指针
} else {
    // 处理失败情况,可能保持原大小或采取其他策略
    printf("Failed to reallocate memory.\n");
}

释放内存:

// 使用完毕后释放内存
free(dynamicArray);
dynamicArray = NULL; // 可选:将指针置为NULL,防止后续误用

动态内存分配函数的实例

1. malloc() 示例

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 分配一个能存储10个整数的空间
    int *dynamicArray = (int*)malloc(sizeof(int) * 10);

    if (dynamicArray == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    // 使用分配的内存
    for (int i = 0; i < 10; ++i) {
        dynamicArray[i] = i * i;
    }

    // 输出动态数组的内容
    for (int i = 0; i < 10; ++i) {
        printf("Element at index %d: %d\n", i, dynamicArray[i]);
    }

    // 释放内存
    free(dynamicArray);
    dynamicArray = NULL;

    return 0;
}
运行结果

在这里插入图片描述

在这个例子中,我们首先使用 malloc() 分配了一个能存储10个整数的空间。然后,我们填充这个动态数组,并打印其内容。最后,我们调用 free() 释放内存,并将指针置为 NULL,防止后续误用。

2. calloc() 示例

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 分配并初始化一个能存储5个浮点数的空间
    float *initializedArray = (float*)calloc(5, sizeof(float));

    if (initializedArray == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    // 使用分配的内存
    for (int i = 0; i < 5; ++i) {
        initializedArray[i] = 1.0f / (i + 1);
    }

    // 输出初始化后的动态数组
    for (int i = 0; i < 5; ++i) {
        printf("Element at index %d: %.2f\n", i, initializedArray[i]);
    }

    // 释放内存
    free(initializedArray);
    initializedArray = NULL;

    return 0;
}
运行结果

在这里插入图片描述

此例中,我们使用 calloc() 分配并初始化了一个能存储5个浮点数的空间。所有元素初始值为0.0。然后,我们填充这个动态数组并打印其内容。最后,我们释放内存并将指针置为 NULL

3. realloc() 示例

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *dynamicArray = (int*)malloc(sizeof(int) * 5);

    if (dynamicArray == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    // 填充初始的动态数组
    for (int i = 0; i < 5; ++i) {
        dynamicArray[i] = i * i;
    }

    // 打印初始数组内容
    printf("Initial array:\n");
    for (int i = 0; i < 5; ++i) {
        printf("Element at index %d: %d\n", i, dynamicArray[i]);
    }

    // 尝试将数组容量扩展至10个元素
    int *temp = (int*)realloc(dynamicArray, sizeof(int) * 10);
    if (temp != NULL) {
        dynamicArray = temp;
        // 填充新增的元素
        for (int i = 5; i < 10; ++i) {
            dynamicArray[i] = i * i;
        }
    } else {
        printf("Failed to reallocate memory. Keeping original size.\n");
    }

    // 打印扩展后的数组内容(或保持原大小)
    printf("Reallocated array:\n");
    for (int i = 0; i < (temp == NULL ? 5 : 10); ++i) {
        printf("Element at index %d: %d\n", i, dynamicArray[i]);
    }

    // 释放内存
    free(dynamicArray);
    dynamicArray = NULL;

    return 0;
}
运行结果在这里插入图片描述

在这个例子中,我们首先使用 malloc() 分配了一个能存储5个整数的空间,并填充了初始值。然后,我们尝试使用 realloc() 将数组容量扩展至10个元素。如果成功,我们填充新增的元素;否则,保持原大小。最后,我们打印扩展后的数组内容(或保持原大小),并释放内存。

注意事项

  • 检查返回值:在使用 malloc()calloc()realloc() 后,应检查返回的指针是否为 NULL,以判断分配是否成功。

  • 避免内存泄漏:当不再需要动态分配的内存时,务必调用 free() 进行释放。忘记释放会导致内存泄漏,长期运行的程序可能因此耗尽系统资源。

  • 匹配类型:分配内存时确保计算的大小与要存储的数据类型相符。使用 sizeof 运算符可以确保正确计算所需字节数。

  • 不要对未分配的内存或已释放的内存进行操作:这会导致未定义行为,严重时程序崩溃。

  • 使用 realloc() 时保护原有数据:如果 realloc() 返回新的地址,记得更新指向内存区域的所有指针,因为原有的内存可能已被移动。同时,如果 realloc() 失败,原内存块保持不变,仍可继续使用。

  • 避免内存碎片:合理规划内存分配与释放,减少频繁的小块内存分配与释放,有助于降低内存碎片,提高内存利用率。

  • 遵循分配与释放对称原则:确保每个 malloc()calloc()realloc() 都有对应的 free() 调用,且释放的是同一指针。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/486373.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

100个openharmony开源demo:1.日历

准备用开发者手机写100个开源的demo不知道能不能实现&#xff0c;日拱一卒&#xff0c;期待蜕变。 第一个demo&#xff1a;日历&#xff0c;借鉴了网上的日历算法&#xff0c;自己用arkts写了界面和点击事件&#xff0c;各位可根据此demo写自己的日历选择器等组件。 1.目录结…

Go——map操作及原理

一.map介绍和使用 map是一种无序的基于key-value的数据结构&#xff0c;Go语言的map是引用类型&#xff0c;必须初始化才可以使用。 1. 定义 Go语言中&#xff0c;map类型语法如下&#xff1a; map[KeyType]ValueType KeyType表示键类型ValueType表示值类型 map类型的变量默认…

python总结-Linux系统使用

设置变量并输出 [rootldpbzhaonan py]$ cat var01.py str1hello str2worldprintf "${str1} ${str2} \n" printf ${str1} ${str2} \n\n就是代表换行&#xff0c;使用printf输出的话&#xff0c;没有自动换行。 不使用换行如下图显示 [rootldpbzhaonan py]$ cat var0…

C语言学习 五、一维数组与字符数组

5.1一维数组 5.1.1数组的定义 数组特点&#xff1a; 具有相同的数据类型使用过程中需要保存原始数据 C语言为了方便操作这些数据&#xff0c;提供了一种构造数据类型——数组&#xff0c;数组是指一组具有相同数据类型的数据的有序集合。 一维数组的定义格式为 数据类型 数…

虚拟+现实,刷新线上直播的“打开方式”

近年来&#xff0c;短视频和线上直播大热&#xff0c;成为我们看世界的途径之一&#xff0c;我们渐渐习惯了看屏幕里面的虚拟世界。随着AIGC技术的不断革新&#xff0c;让虚拟直播间的体验感越来越真实&#xff0c;给我们带来了不同寻常的体验。 虚实融合&#xff0c;超越传统…

将ORB-SLAM3用图像增强的方式打开

ORB-SLAM3在复杂光照环境下&#xff0c;特征提取和特征匹配的性能明显下降&#xff0c;其准确性和鲁棒性收到很大影响&#xff0c;尤其是当周围环境获取的ORB特征点数量不足时&#xff0c;位姿的估计过程无法进行&#xff0c;甚至或导致初始化和跟踪失败的情况&#xff0c;目前…

03、Lua 基本语法

Lua 基本语法 Lua 基本语法第一个 Lua 程序交互式编程脚本式编程 注释单行注释多行注释 标示符关键词全局变量 Lua 基本语法 Lua学习起来非常简单&#xff0c;我们可以创建第一个 Lua 程序&#xff01; 第一个 Lua 程序 交互式编程 Lua提供了交互式编程模式。我们可以在命令…

开始喜欢上了runnergo,JMeter out了?

RunnerGo是一款基于Go语言、国产自研的测试平台。它支持高并发、分布式性能测试。和JMeter不一样的是&#xff0c;它采用了B/S架构&#xff0c;更灵活、更方便。而且&#xff0c;除了API测试和性能测试&#xff0c;RunnerGo还加上了UI测试和项目管理等实用功能&#xff0c;让测…

蓝桥杯刷题-串的处理

串的处理 代码 s input().split() l_new [] for i in s:i list(i)new""for j in range(len(i)-1): # 遍历newi[j]if i[j].isdigit() and i[j1].isalpha(): # 在字母和数字之间添加“_”new_if i[j].isalpha() and i[j1].isdigit(): # 同上new_newi[-1]l_new.appe…

K3 计划订单投放时,将“关联物料”传递到采购和生产订单的“组部件”字段

参考K/3 WISE 中MRP计算投放过程中 销售订单自定义字段怎么携带到任务单这篇文章&#xff0c;进行优化。 在表ICMrpDestBills下增加触发器&#xff0c;代码如下 CREATE TRIGGER [dbo].[ICMrpDestBills_update]ON [dbo].[ICMrpDestBills]AFTER INSERT,UPDATE AS BEGINSET NO…

mysql 设置初始密码

link 1.首先输入以下指令&#xff1a; sudo cat /etc/mysql/debian.cnf运行截图如下&#xff1a; 2. 再输入以下指令&#xff1a; mysql -u debian-sys-maint -p//注意! //这条指令的密码输入是输入第一条指令获得的信息中的 password ZCt7QB7d8O3rFKQZ 得来。//请根据自己的实…

【CKA模拟题】如何发布一个SVC资源

题干 For this question, please set this context (In exam, diff cluster name) kubectl config use-context kubernetes-adminkubernetesYou have an existing Nginx pod named nginx-pod . Perform the following steps: Expose the nginx-pod internally within the cl…

Linux系统部署Paperless-Ngx文档管理系统结合内网穿透实现公网访问

文章目录 1. 部署Paperless-ngx2. 本地访问Paperless-ngx3. Linux安装Cpolar4. 配置公网地址5. 远程访问6. 固定Cpolar公网地址7. 固定地址访问 Paperless-ngx是一个开源的文档管理系统&#xff0c;可以将物理文档转换成可搜索的在线档案&#xff0c;从而减少纸张的使用。它内置…

二手车交易网站|基于JSP技术+ Mysql+Java+ B/S结构的二手车交易网站设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

一些恶意样本的流量分析学习

Trickbot Trickbot 是一种自 2016 年以来一直在感染受害者的信息窃取者和银行恶意软件。Trickbot通过恶意垃圾邮件&#xff08;malspam&#xff09;分发&#xff0c;也由其他恶意软件&#xff08;如Emotet&#xff0c;IcedID或Ursnif&#xff09;分发。 分析来自恶意垃圾邮件…

Frida 官方手册 中文版 ( 机翻+人翻 )

Frida 英文文档&#xff1a;https://frida.re/docs/home/ Frida 中文文档&#xff1a;https://pypi.org/project/frida-zhongwen-wendang/ 目的&#xff1a;给自己一个认真阅读文档的机会&#xff01;&#xff01;&#xff01; 部分名词找不到合适的中文表达&#xff0c;直接使…

计算机视觉技术:美颜SDK在直播平台的集成与优化

当下&#xff0c;美颜技术在直播平台中的应用变得愈发重要。接下俩&#xff0c;小编将深度讲解计算机视觉技术在美颜SDK集成与优化方面的应用&#xff0c;以提升直播平台的用户体验。 一、美颜技术的发展 传统的美颜功能只是简单地对图像进行柔化处理&#xff0c;而现在的美颜…

你真的会数据结构吗:堆

❀❀❀ 文章由不准备秃的大伟原创 ❀❀❀ ♪♪♪ 若有转载&#xff0c;请联系博主哦~ ♪♪♪ ❤❤❤ 致力学好编程的宝藏博主&#xff0c;代码兴国&#xff01;❤❤❤ 好久不见&#xff0c;甚是想念&#xff0c;不知道大家有没有察觉到大伟的头像和名字变了鸭 <(*&#xffe…

RK3568驱动指南|第十三篇 输入子系统-第151章 通用事件处理层read和write函数分析

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

Leetcode第26题:删除有序数组中的重复项

代码实现 注意:该题要求原地删除&#xff0c;不能引入额外的连续内存空间 class Solution:def removeDuplicates(self, nums: List[int]) -> int:not_sorted_lengthlen(nums)while(not_sorted_length>0):numnums.pop(0)not_sorted_length-1if num not in nums:nums.appe…