动态内存分配malloc(进阶版)

在上一篇(初阶版)我们简单阐述了malloc()函数的相关知识,掌握了基本用法和原理,以及free()函数用于释放空间,想了解malloc用法的可以转场上一篇文章看看再来。本篇文章主要分享一些初学malloc()函数时的细节性小问题和一开始困扰我的“十万个为什么”。

首先回顾一下上一篇中的参考代码;

​
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int n;
    scanf("%d",&n);
    //输入
    int *str1=(int*)malloc(n*sizeof(int));
    //动态内存分配
    if(str1==NULL)
    {
        return 1;
    }
    //判断是否开辟成功
    for(int i=0;i<n;i++)
    {
        scanf("%d",&str1[i]);
    }
    //输入数组中的值
    for(int i=0;i<n;i++)
    {
        printf("%d",str1[i]);
    }
    //输出数组
    free(str1);
    //释放内存
    return 0;
}

​

 malloc()函数的使用形式

数据类型 *指针变量 = (数据类型 *)malloc(要分配的内存大小);

int *str1=(int*)malloc(n*sizeof(int));

该函数用于分配指定大小的内存,并将返回的内存地址赋值给指针变量;

 在参考代码中,不难发现他们的一一对应关系;

数据类型*指针变量:

这是一个指向特定数据类型的指针变量。其中,数据类型表示指针所指向的对象的类型,*表示声明的是一个指针变量;

(数据类型*):

这是强制类型转换操作,将malloc函数返回的内存地址转换为指定类型的指针;

malloc(要分配的内存大小):

malloc是C标准库里的一个函数,用于动态分配指定大小的内存块。比如int类型在计算机上通常占4个字节,malloc(4*sizeof(int))就开辟出16个字节大小的空间

以上是对该函数的细节分享,下面分析一下我自己编程过程中遇到的相关问题;


 为什么malloc(n*sizeof(int))而非malloc(sizeof(int))

控制要分配的空间大小呗~  认真看了前文的都知道,n*sizeof(int)意为n个整形数据需要的空间大小

为什么数据变多了没发生溢出

当我用动态内存分配存储两个数组并且把第二个数组衔接到第一个数组后,居然正常输出了;但是理论上加入数组2的数据后,数组1应该要发生数据溢出才对,所以修改代码后,输出数组的首地址和各个元素的地址

代码和结果

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    //输入
    int *str1=(int*)malloc(n*sizeof(int));
    int *str2=(int*)malloc(m*sizeof(int));
    printf("str1地址(前)%p\n",&str1);
    printf("str2地址(前)%p\n",&str2);
    printf("\n");
    //动态内存分配
    if(str1==NULL)
    {
        return 1;
    }
    if(str2==NULL)
    {
        return 1;
    }
    //判断是否开辟成功
    for(int i=0;i<n;i++)
    {
        scanf("%d",&str1[i]);
    }
    for(int i=0;i<m;i++)
    {
        scanf("%d",&str2[i]);
    }
    //输入两个数组中的值
    for(int i=0;i<n;i++)
    {
        printf("%d str1元素(前)%p\n",str1[i],&str1[i]);
    }
    printf("\n");
    for(int i=0;i<m;i++)
    {
        printf("%d str2元素(前)%p\n",str2[i],&str2[i]);
    }
    printf("\n");
    printf("\n");
    for(int i=0;i<m;i++)
    {
        str1[i+n]=str1[i];
    }
    for(int i=0;i<n+m;i++)
    {
        printf("%d str1元素(后)%p\n",str1[i],&str1[i]);
    }
    printf("\n");
    for(int i=0;i<m;i++)
    {
        printf("%d str2元素(后)%p\n",str2[i],&str2[i]);
    }
    printf("\n");
    printf("\n");
    printf("str1地址(后)%p\n",&str1);
    printf("str2地址(后)%p",&str2);
    free(str1);
    free(str2);
    return 0;
}

原因分析【动态内存分配&数组】

 动态内存分配和数组存储信息的原理相似但也存在区别

相同处

 1.都是用于存储多个相同类型的数据元素

 2.都使用连续的内存空间来存储数据

动态内存分配的“高级之处”

1.动态内存分配可以根据实际运用规定任意大小的内存块,malloc()函数、calloc()函数和realloc()函数的灵活程度和修改方式略有不同。

2.动态内存分配使用指针来访问和操作内存空间,通过指针可以读写、释放等等。

3.动态内存分配可以存储不同类型的数据。

所以为什么数组1没发生溢出呢?

 理论上,在C语言中,当你分配动态内存时,系统会为你分配指定大小的内存空间。如果你在使用这些内存时超越了分配的空间,会发生缓冲区溢出,这可能导致程序崩溃或者是其他不可预测的行为。

在该代码中,虽然str1的空间明显小于最后把str2复制后加上的str1,但是并没有发生数据溢出的情况,这是因为在C语言中,数据的大小是固定的,一旦定义后无法改变。当你尝试将超过str1容量的元素复制到str1中时,会发生越界访问(这种逆天操作可能会导致程序崩溃、数据损坏、安全漏洞或其他未知问题),这是一种未被定义的危险行为。所以最后几个元素是被写入了str1数组边界的位置(程序运行没有出错大概率是因为数组和动态内存分配都是连续的空间,它们被罗列到数组后面了,但是这并不安全)

  • 35
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值