C语言学习(三十五)---动态内存练习题与柔性数组

news2024/9/21 8:08:44

经过前面的内容,我们已经对动态内存的知识已经有了相当多了了解,今天我们再做几道有关动态内存的练习题,然后再介绍一下柔性数组,好了,话不多说,开整!!!

动态内存练习题

题目分析

先自行分析以下代码,分析错误在哪以及运行结果,然后再查看解析:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory(char* p)
{
    p = (char *)malloc(100);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(str);
    strcpy(str,"hello world");
    printf(str);
    free(str);
    str = NULL; 
}
int main()
{
    Test();
    return 0;
}

自行分析完毕后,再来查看该部分分析:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory(char* p)
{
    p = (char *)malloc(100);//2、向动态内存申请100个字节的空间,然后返回一个char*的指针变量
    return p;//返回该指针
}
void Test(void) //1、进入该函数
{
    char* str = NULL;  //定义一个空的字符指针,str为一个值
    GetMemory(str);//进入该自定义函数 :由于此处传入的非地址,因此,内部的操作在退出GetMemory函数后
    // 会自动销毁,因此申请无效,并且申请的动态内存未销毁
    strcpy(str,"hello world");//3、走出上一个自定义函数,进行字符串拷贝
    //此处进行拷贝,由于并没有申请成功,str仍为空指针,因此程序崩溃
    printf(str);//打印内容 :没有拷贝成功,因此,也不会打印出结果
    free(str);//释放空间 :释放空指针所在的空间,
    //没有置空
}
int main()
{
    Test();//执行到此处,进入自定义函数Test
    return 0;
}

所以程序会崩溃,运行结果如下:
在这里插入图片描述
同样在Linux下可以更明显的看到该错误:
在这里插入图片描述

题目改正

在前面的内容中我们讲到过:如果想在自定义函数的内部操作,影响外部的值,则需要传址

因此我们此时传入str的地址,既然传入的为一个地址,那么接收就应该为二级指针char**

既然是向动态内存申请空间并要使用,那我们就直接解引用p,最后再对动态内存进行置空,因此,改正代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory(char** p)
{
    *p = (char *)malloc(100);
}  
void Test(void) 
{
    char* str = NULL; 
    GetMemory(&str);
    strcpy(str,"hello world");
    printf(str);
    free(str);
    str = NULL; 
}
int main()
{
    Test();
    return 0;
}

查看结果,发现结果正确:
在这里插入图片描述

柔性数组

这个概念,其实很多人都是第一次听说,我们之前学习过数组,那么柔性数组是什么呢,

当在定义的结构体中,最后一个元素的大小是未知的,可以根据使用需要自行开辟

这样所定义的就是柔性数组,从概念中可以看到,这我们学的动态内存有些相似之处都是可以根据需要调整所用的空间

其用法为:

结构体指针 p = (结构体指针)malloc(结构体空间 + 自定义空间)

比如以下代码:

#include<stdio.h>
#include<stdlib.h>
struct test
{
    int a;
    int arr[];
};
int main()
{
    struct test* p = (struct test*)malloc(sizeof(struct test) + 40);
    int i = 0;
    if (p == NULL)
    {
        return 0;
    }
    else
    {
    for(i=0;i<10;i++)
    {
        p->arr[i] = i;
        printf("%d ",p->arr[i]);
    }
    }
    free(p);
    p = NULL;
    return 0;
}

在上述的代码中,我们就声明了一个柔性数组,然后申请了40字节的空间,进行赋值,编译结果如下:
在这里插入图片描述
当然了,在后续的使用,也可以使用realloc函数进行空间再调整

除了上述的方式外,也有另一种方式,直接再结构体的最后一个元素定义一个指针,然后用指针指向一片待开辟的空间,也可以实现这个功能,代码如下:

#include<stdio.h>
#include<stdlib.h>
struct test
{
    int a;
    int* arr;
};
int main()
{
    struct test* p = (struct test*)malloc(sizeof(struct test));
    int i = 0;
    p->arr = malloc(5*sizeof(int));//申请5个整型空间给数组指针arr
    if ( p == NULL)
    {
        return 0;
    }
    else
    {
        for(i=0;i<5;i++)
        {
            p->arr[i] = i;
            printf("%d ",p->arr[i]);
        }
    }
    free(p->arr);
    p->arr = NULL;
    free(p);
    p = NULL;
    return  0;
}

在上述的代码中,我们就是用另外一种方式实现了柔性数组的功能,但是可以看到,在释放动态内存时,需要分两次释放先释放数组指向的动态内存,再释放p指向的动态内存空间,因此,在使用中,容易产生错误

不推荐大家使用。

上述内容即使今天的全部内容了,感谢大家的观看。
如果方便,辛苦大家点个赞和关注哦!
您的点赞或评论或关注是对我最大的肯定,谢谢大家!!!

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

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

相关文章

上海亚商投顾:沪指失守3200点 两市成交不足8000亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 沪指今日延续调整&#xff0c;失守3200点关口&#xff0c;深成指、创业板指盘中均跌超1%。AI概念股集体下挫&#…

你会做接口测试吗?接口测试面试题盲扫(附答案)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 为什么要做接口测…

【跑实验06】如何数据集中加入图像尺寸?如何把tuple格式的坐标按顺序写成四列数据?如何把某一列放到最后?

文章目录 一、如何数据集中加入图像尺寸&#xff1f;二、如何把tuple格式的坐标按顺序写成四列数据&#xff1f;三、如何把某一列放到最后&#xff1f; 一、如何数据集中加入图像尺寸&#xff1f; 部分核心代码如下&#xff1a; image_files [filename for filename in os.l…

Windows | \\wsl.localhost无法访问

Windows | \\wsl.localhost无法访问 在地址栏输入&#xff1a;\\wsl.localhost或者\\wsl.localhost\

解决新版Pyahcrm2023.1.2版本没有manage repositories按钮无法更改依赖源的问题及使用Pycharm安装库的新理解

本文章的理解基于下面两篇文章&#xff1a; https://blog.csdn.net/henu1710252658/article/details/130918206 https://blog.csdn.net/henu1710252658/article/details/82015796 问题一&#xff1a;新版Pyahcrm2023.1.2版本没有manage repositories按钮无法更改依赖源 首先&am…

高效读深度学习代码:如何又快又好的get代码的逻辑与思想

犹豫很久要不要把读代码这个事情专门挑出来写成一篇推文。毕竟读代码嘛&#xff0c;大家可能都会读。而且笔者个人读的和写的代码量也并不足以到指导大家读代码的程度。但笔者还是决定大胆地写一点&#xff1a;就当是给自己设立今后读代码的标准&#xff0c;也将一些之前未能践…

浏览器相关面试题

1、在浏览器中输入URL并回车后发生了什么 https:www.baidu.com url > 统一资源定位发&#xff0c;&#xff08;网址&#xff09; 是IP的一个映射&#xff0c;方便记忆 https&#xff1a;传输协议&#xff08;http和TCP之间加了一层TSL或者SSL的安全层&#xff09; www&a…

在Ubuntu中禁用和启用CPU内核详解

概要 在某些情况下&#xff0c;您可能需要在Ubuntu操作系统中禁用或启用CPU内核。禁用CPU内核可以帮助您降低功耗&#xff0c;提高性能或解决一些与硬件和软件兼容性相关的问题。本文将介绍如何在Ubuntu中禁用和启用CPU内核的方法。 方法一&#xff1a;使用GRUB配置 GRUB是Ubu…

谷歌验证码kaptcha使用(包括前端获取获取解析)

1.后端 基于springboot开发。 包结构 1.导入依赖 <!--kaptcha验证码生成器--><dependency><groupId>com.github.axet</groupId><artifactId>kaptcha</artifactId><version>0.0.9</version></dependency> 2.配置类 …

从零开始:深度学习入门资料推荐

还记得几年前刚入坑的时候&#xff0c;老师给的入门资料就是一堆论文&#xff01;害的我差点放弃。。。 如今深度学习应用的开发成本越来越低&#xff0c;学习资料越来越多&#xff0c;于是对初学者来说进入了另一个相反的困境——资料过多&#xff0c;让人眼花缭乱&#xff0…

ASEMI整流桥MB6S是什么电子元件

编辑-Z 在电子工程领域&#xff0c;整流器是一种常见的电子设备&#xff0c;用于将交流电&#xff08;AC&#xff09;转换为直流电&#xff08;DC&#xff09;。其中&#xff0c;整流桥MB6S是一种广泛使用的整流器&#xff0c;以其高效、稳定和可靠的性能赢得了工程师们的青睐…

[Container]Hadoop集群镜像打包

文章目录 Docker DNS配置Linux Docker DNS设置Windows、MacOs Docker DNS设置 打包HadoopDockerfile打包文件参数声明和基础镜像引入安装相关依赖库创建普通用户下载或导入软件包环境变量配置 初始化脚本参数配置${HADOOP_CONF_DIR}/workers工作节点${HADOOP_CONF_DIR}/hadoop-…

97、基于stm32单片机智能药箱药盒温湿度体温光照时钟wifi手机APP监控(程序+原理图+PCB源文件+手机APP源码+硬件设计资料+元器件清单等)

单片机类型选择 方案一&#xff1a;可以使用现在比较主流的单片机STC89C5单片机进行数据处理。这款单片机具有的特点是内存和51的单片机相比多了4KB内存&#xff0c;但是价格和51单片机一样。并且支持数据串行下载和调试助手。此款单片机是有ATMEL公司生产&#xff0c;可用5V电…

appium自动化测试之PO模型设计

目录 PO模型 PO分层 PO模型设计框架 config目录 common目录 pages目录 function目录 case目录 logs目录 report目录 runTest.py文件 总结&#xff1a; 我们在做自动化的时候应该都听过PO模型&#xff0c;那么什么是PO模型呢&#xff1f;PO模型在自动化中的作用是什…

【链表OJ】删除链表中重复的结点

⭐️ 往期链表相关OJ &#x1f4ab;链接1&#xff1a;链表分割 &#x1f4ab;链接2&#xff1a;链表中倒数第k个结点(快慢指针问题) &#x1f4ab;链接3&#xff1a;leetcode 876.链表的中间结点(快慢指针问题) &#x1f4ab;链接4&#xff1a;leetcode 206.反转链表 &#x1…

第二章React全家桶之面向组件编程

文章目录 一、组件的基本理解和使用1-1、函数式组件1-2、类式组件 二、组件实例的三大核心属性2-1、state的基本使用2-2-1、state的总结 2-2、props的基本使用2-2-1、props的传值与批量传值2-2-2、对props进行限制2-2-3、props的简写2-2-4、类式组件中的构造器与props2-2-5、函…

使用 eKuiper 按需桥接 CAN Bus 数据至 MQTT

CAN Bus 是一种广泛应用于汽车和工业领域的通信协议&#xff0c;它能够让多个设备在同一网络中进行交互。而 MQTT 是一种广泛应用于物联网领域的通信协议&#xff0c;作为一种轻量级的发布-订阅消息传输协议&#xff0c;它有效地促进了机器之间的通信。 通过将 CAN Bus 数据桥…

Vue组件库Element-常见组件-分页

常见组件-Pagination 分页 Pagination 分页&#xff1a;当数据过多时&#xff0c;会使用分页分解数据 具体关键代码如下&#xff1a;&#xff08;重视注释&#xff09; <template><div><!-- Pagination 分页 --><el-pagination background layout"…

Etsy店铺被封的原因是什么?如何防封

ETSY是一个全球知名的在线市场和电商平台&#xff0c;专注于手工艺品、独特商品和创意艺术。它为卖家提供了一个平台来展示和销售自己的手工制品、艺术品、珠宝、家居用品、时尚配饰等各种创意产品。作为一个颇受中国商家青睐的平台&#xff0c;Etsy在账号检测方面也是不亚于亚…

微软MFC技术中消息的分类

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天来聊聊MFC技术中消息的分类。 微软Windows中的消息虽然很多&#xff0c;但是种类并不繁杂&#xff0c;大体上有3种&#xff1a;窗口消息、命令消息和控件通知消息。 窗口消息 窗口消息是系统中最为常见…