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

news2024/9/23 7:25:20

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() 调用,且释放的是同一指针。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis分布式锁—SETNX+Lua脚本实现

使用redis实现分布式锁&#xff0c;就是利用redis中的setnx&#xff0c;如果key不存在则进行set操作返回1&#xff0c;key已经存在则直接返回0。 优点&#xff1a; 设置expiretime过期时间&#xff0c;可以避免程序宕机长期持有锁不释放。redis作为一个中间服务&#xff0c;所…

成都百洲文化传媒有限公司引领电商服务新潮流

在当今数字化时代&#xff0c;电商行业日新月异&#xff0c;竞争激烈。然而&#xff0c;在这个浪潮中&#xff0c;成都百洲文化传媒有限公司凭借其专业的电商服务&#xff0c;脱颖而出&#xff0c;成为了行业中的新领军者。今天&#xff0c;我们就来探讨一下这家公司如何在这个…

详解mysql安装与配置,及Mac中常见的安装问题

目录 1 数据库介绍 什么是数据库 数据库分类 2 MySQL服务器安装 2.1 Windows绿色安装 2.2 Windows中重装MySQL 3 Mac中常见的安装问题 4 客户端连接MySQL服务器 5 SQL分类 1 数据库介绍 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件…

面试算法-103-对链表进行插入排序

题目 给定单个链表的头 head &#xff0c;使用 插入排序 对链表进行排序&#xff0c;并返回 排序后链表的头 。 插入排序 算法的步骤: 插入排序是迭代的&#xff0c;每次只移动一个元素&#xff0c;直到所有元素可以形成一个有序的输出列表。 每次迭代中&#xff0c;插入排序…

下载的音频转换成mp3怎么转?4个好用简单的方法

不同音乐平台下载的音频格式文件不同&#xff0c;比如网易云的ncm格式、酷狗的kgm格式、B站的m4s格式、微信语音的silk格式、手机录音的amr、m4a格式&#xff0c;这些音频一旦脱离了原本的平台便无法播放&#xff0c;那么如何把下载的音频转换成兼容性高的MP3格式以便于我们在更…

BoostSeacher

前言&#xff1a; 基于Boost库的搜索引擎 为何基于Boost库&#xff1f; 从技术上说&#xff1a;这个项目用了很多Boost库的接口从搜索引擎存储内说&#xff1a;存储的内容是Boost库的内容预期效果 预期效果:用户在浏览器输入关键词&#xff0c;浏览器显示相关结果 STEP1&#x…

问题记录:idea中的目标字节码版本总是自动更改为1.5

问题描述&#xff1a; 图中画圈的地方应该是1.8 但是总是自动被还原到1.5 解决方法&#xff1a;在pom文件中加入,注意加入到内中&#xff0c;作为子节点 <build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version…

Python编程异步爬虫实战案例

aiohttp异步爬取实战 案例介绍 链接为https://spa5.scrape.center&#xff0c;页面如下图所示&#xff1a; 这是一个图书网站&#xff0c;整个网站包含数千本图书信息&#xff0c;网站数据是JavaScript渲染而得的&#xff0c;数据可以通过Ajax接口获取&#xff0c;并且接口没…

关于YOLOv9项目中使用已有模块自由改进的教程

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 1. 文件说明 在YOLOv5-v9&#xff0c;模型的结构是以yaml文件的存储。我们可以在原有的yaml基础上增、减、改模块&#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…

高德地图加遮罩灯光效果

最近做大屏展示&#xff0c;UI突然有一个大胆的想法&#xff0c;他想把地图做成那种有点灯光照在上面的感觉&#xff0c;经过几番尝试后终于实现了相关效果&#xff0c;特此分享&#xff1b; 效果图 实现方式-css /* 高德地图加载成功有一个amap-layers类名的标签&#xff0c;…

论文不再难写:ChatGPT带你飞

目录 一、ChatGPT&#xff1a;您的个人写作顾问 1.打造个性化的论文框架 2.提升写作质量与效率 3.丰富表达方式&#xff0c;增强文章吸引力 二、结语&#xff1a;开启写作新篇章 在这个信息迅速发展、日新月异的时代里&#xff0c;写作已成为我们表达自我、在学术界或职场…

406. 根据身高重建队列(力扣LeetCode)

文章目录 406. 根据身高重建队列题目描述贪心算法代码 406. 根据身高重建队列 题目描述 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi &…

瑞萨杯(一)

基础信息 RA6M5&#xff1a;ARM V8架构&#xff0c;24MHz外置晶振&#xff0c;200MHz主频 SCI&#xff08;Serial Communications Interface&#xff09;&#xff0c;意为串行通信接口 参考链接&#xff1a; 【瑞萨RA系列FSP库开发】RASCKeil的环境搭建_瑞萨ra mdk-CSDN博客…

24 OpenCV直方图反向投影

文章目录 参考反向投影作用calceackProject 反向投影mixchannels 通道图像分割示例 参考 直方图反向投影 反向投影 反向投影是反映直方图模型在目标图像中的分布情况简单点说就是用直方图模型去目标图像中寻找是否有相似的对象。通常用HSV色彩空间的HS两个通道直方图模型 作用…

Excel表格中函数CEILING的用法

这里写目录标题 CEILING函数将参数Number向上舍入 CEILING函数将参数Number向上舍入 CEILING函数是将参数Number向上舍入&#xff0c;沿绝对值增大的方向&#xff0c;为最接近的 significance 的倍数。其语言表达为&#xff1a;CEILING(number, significance)

[flask]cookie的基本使用/

彻底理解 Cookie - 知乎 (zhihu.com) 是什么 cookie是当你浏览某个网站的时候&#xff0c;由web服务器存储在你的机器硬盘上的一个小的文本文件。它其中记录了你的用户名、密码、浏览的网页、停留的时间等等信息。当你再次来到这个网站时&#xff0c;web服务器会先看看有没有…

简析:创业老隋推荐的蓝海项目到底好不好做?

在当前的创业浪潮中&#xff0c;网红创业凭借其独特的优势和影响力&#xff0c;成为了不少年轻人追逐的梦想。老隋&#xff0c;作为网红创业领域的佼佼者&#xff0c;凭借其丰富的经验和敏锐的洞察力&#xff0c;经常为粉丝们推荐一些看似前景广阔的蓝海项目。那么&#xff0c;…

吴恩达2022机器学习专项课程(一) 3.3 成本函数的公式

问题预览 模型的参数&#xff08;w和b&#xff09;有什么作用&#xff1f;不同的w和b对线性回归模型有什么影响&#xff1f;训练集里的y和线性回归模型预测的y&#xff08;y帽&#xff09;的区别是什么&#xff1f;成本函数的作用是什么&#xff1f;成本函数的公式是什么&…

众邦科技CRMEB商城商业版任意文件写入getshell 0day

代码审计 接口&#xff1a;/adminapi/system/crud 处理的代码如下 public function save(SystemCrudDataService $service, $id 0){$data $this->request->postMore([[pid, 0],//上级菜单id[menuName, ],//菜单名[tableName, ],//表名[modelName, ],//模块名称[table…