c++ - malloc既然是动态分配,为什么还要指明size?

浏览:61日期:2023-03-27

问题描述

在如下代码中的insert()函数中,插入一个数据之后,cnu++可以理解,为什么len也要有len++ ?如果这样的话,岂不是永远可以无限插入数组元素?那么判断是否full还有什么意义呢?另外,我在按如下代码运行的时候,初始化数组的时候分配了6个空间,还能插入第7个,第8个元素,那么这些元素存储哪里来的空间?是malloc自动分配的吗?如果我加一个元素malloc就自动分配空间,那为什么用malloc时还要指明size?

#include<stdio.h>#include<malloc.h>#include<stdbool.h>struct Arr{int len;//数组能存取的最大元素个数int cnu;//数组中当前元素个数int * pBase;//存储指向数组的指针};/***初始化数组*/void init_array(struct Arr * pArray,int len){pArray->pBase=(int *)malloc(sizeof(int)*len);//分配4*len字节长度的内存if(NULL== pArray->pBase)//判断内存是否分配失败{ printf('动态分配内存失败n'); // exit(-1);}else{pArray->len=len;pArray->cnu=0;}return ;}/***判断数组是否为空,传地址省内存4字节,传结构体变量需要进行拷贝,12字节*/bool isempty(struct Arr * pArray){if(0==pArray->cnu){ return true;}else{return false;}}/****判断数组是否满了*/bool isfull(struct Arr * pArray){ if(pArray->len==pArray->cnu) { return true; }else { return false; }}/***显示数组内容*/void show_array(struct Arr * pArray){if(isempty(pArray)) printf('数组为空!n');else{ int i; for( i=0; i<pArray->cnu;i++) {printf('%d n',pArray->pBase[i]); } printf('------------------------------------n');}}/****向数组追加元素*/bool append(struct Arr * pArray,int val){if(isfull(pArray)){ printf('数组已经满了!n'); return false;}else{ pArray->pBase[pArray->cnu]=val; pArray->cnu++;}}/****向数组中插入元素,pos为数组中第几个位置,pos=3就是向a[2]插入元素*/bool insert(struct Arr * pArray,int pos,int val){ if(pos<1||pos>pArray->len+1)//插入的位置不能小于1,同时不能比最后一个元素大二 { printf('插入的位置输入的不合法n'); return false; } if(isfull(pArray)) { printf('数组已经满了,插入失败!n'); return false; } int i; //循环将pos位置开始的数组后移 for(i=pArray->cnu;i>=pos;i--) //移动范围是从第pos个到底cnu个 { pArray->pBase[i]=pArray->pBase[i-1]; /** 若以i表示要移动元素的位置,从一开始的。右边都是i-1,若左移,左边是i-2,右移,左边是i */ } pArray->pBase[pos-1]=val; pArray->cnu++; pArray->len++; return true;}/****删除数组中的第pos个元素,同时返回删除的元素的值*/bool delete(struct Arr * pArray,int pos,int * val){ if(pos<1||pos>pArray->cnu) { printf('删除失败,位置不合法n'); return false; } int i; *val=pArray->pBase[pos-1]; for(i=pos+1;i<=pArray->cnu;i++) { //移动单位是从第pos+1个到cnu pArray->pBase[i-2]=pArray->pBase[i-1]; } pArray->cnu--; return true;}/****数组倒置*/bool inverse(struct Arr * pArray){if(isempty(pArray)){ printf('倒置失败,因数组为空'); return false;}int i=0;int j=pArray->cnu-1; int temp;while(i<j){ temp=pArray->pBase[i]; pArray->pBase[i]= pArray->pBase[j]; pArray->pBase[j]=temp; i++; j--;}return true;}int main(){ struct Arr arr; init_array(&arr,6);//将结构体的地址作为实参,这样才能修改结构体中的值,如果传的是结构体变量,那么将进行拷贝,不会改变值 append(&arr,1); append(&arr,2); append(&arr,3); append(&arr,4); show_array(&arr); insert(&arr,2,88); show_array(&arr); int val; delete(&arr,1,&val); show_array(&arr); printf('删除了 %dn',val); inverse(&arr); show_array(&arr); return 0;}

问题解答

回答1:

len++是代码写错了

malloc只是向系统申请一块固定大小的内存,并且把起始地址返回给你,并不会自动调整。第7 第8个元素已经溢出了,会覆盖这6个空间之后的两个内存单元,如果这两个内存单元存放着别的数据,就会导致未知的错误

能插入8个元素还是因为len++这个bug,每次insert都会让len++,通过比较len和cnu,数组永远都不会full

回答2:

代码应该有问题。Arr如果是动态数组(可根据需要扩容),那append就应该可以一直操作,除非没有内存了;如果不是可扩展的,那么len就不应该变。

malloc 肯定要指定size啊,它只管分配多少字节的内存。

相关文章: