帮别人调试个程序,程序的功能主要涉及动态数组。实现动态数组元素的加入,删除,查找。显示功能。可是在运行加入功能的时候,连续运行三次加入的时候就会出现故障,让人感到很的莫名其妙。

涉及到的函数例如以下所看到的:

void adddata(int * arr, int * len)
{int n;int *add;int cnt=0, t1;printf("pleaseenter the amount of element you want to add;\n");scanf("%d",&n);add = (int*)malloc(sizeof(int)* n);inputdata(add, n); //把用户要加入的数据加入一个新的数组。t1 = *len; //以下循环实用,当用户输入的数都大于不论什么数的时候用的*len = *len + n ; //又一次定义下数组长度,依据用户要扩充的大小。realloc(arr, sizeof(int)*(*len));   for (i=0;i<n; ++i)                                                   // i 循环是循环要加入的数{for(j=0; j<t1+i; ++j)                                               // j循环是循环原数组{if( add[i] < arr[j]){for (k=j; k <= t1+i; ++k){t =arr[k];arr[k]= add[i];add[i]= t;}cnt = 1;break;}cnt = 0;}if( 0 == cnt)arr[t1+i]=add[i];}resultdata(arr, *len);switch_choice (arr, * len);
}

从这里能够看到这段程序的缺点:

<1>全局变量的滥用。只是这里没有造成错误

<2>realloc函数不适用返回值。后面会知道这是罪魁祸首

<3>malloc的add没有在函数结束的时候释放

1 针对函数的缺点。我们一一侦破,先是在函数的结尾加上对add的释放

if(add != NULL){free(add);add = NULL;}

可是第一次释放add就会出现以下的问题。运行调试,发现是在free的时候出现了问题。也就是free居然失败了。

2 然后再加上对realloc函数的改动

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

Realloc函数会针对不同的情况运行不同的行为,假设realloc函数运行成功,那么函数会返回新的内存空间的首地址。而且free掉之前 的内存空间。而且之前的内存内容拷贝到新的内存中。假设开辟失败,那么之前的内存空间不会被释放,realloc函数返回NULL。所以在添加内存的时候。万万不可使用一直使用原来的全局指针,原因就是它可能已经被free掉,而新的指针指向发生了变化。

同一时候假设继续使用原来的全局指针,就可能发生数组的越界,越界就会破坏堆,终于连其他的跟操作内存的函数运行都会出现故障。

如今把void adddata(int * arr,int * len)

中的realloc函数改动成例如以下:

tmp = (int*)realloc(arr, sizeof(int)*(*len));if( tmp!= NULL){arr = tmp;tmp = NULL;}else{printf("reallocmemory failed\n");exit(1);}

然后測试。一切OK,这说明了罪魁祸首的确是realloc函数的错误使用,realloc不会保证新内存的首地址还是原来的。它非常可能发生变化。

3 针对realloc函数错误调用后,发生数组越界会造成free失败的验证

測试代码例如以下所看到的:

#include <stdio.h>
#include <stdlib.h>void main()
{   int n = 3;int na;int i;int *p2;int *p = (int*)malloc(sizeof(int)*n);int *p3 = ( int*)malloc(sizeof(int)*3 );p3[0] = 11;p3[1] = 22;p3[2] = 33;for(i=0;i<n;i++){p[i] = i;}for(i=0;i<n;i++)printf("%d\n",p[i]);printf("input mount of number to add:");scanf("%d",&na);p2 = (int*)realloc( p,sizeof(int)*(n+na) );for(i=n;i<n+na;i++){p2[i] = i;}p[n+na+ 10] = 0;    // out range of pfor(i=0;i<n+na;i++)printf("%d\n",p2[i]);printf("now can see\n");for(i=0;i<n;i++)printf("%d\n",p[i]);if( p3 != NULL)    //failed because of p's outof range{free(p3);p3 = NULL;}}

运行结果:

这个就说明了一切问题。p的越界造成了无辜的p3跟着遭殃,p3到最后都不能进行释放。

附录(改动后的完整的功能程序):

#include <stdio.h>
#include <stdlib.h>void inputdata( int * arr, int len);
void arrangeinorder( int * arr, int len);
void resultdata(int*, int);
void switch_choice(int * , int );
void finddata( int * arr, int len);
void deletedata(int * arr, int * len);
void adddata(int * arr, int * len);int main (void)
{   int *arr;int len;printf ("enter the amount of data that you will input: ");scanf("%d", &len);arr = (int *) malloc( sizeof(int) * len);inputdata(arr, len);          //单独測试可用(用来输入数组)arrangeinorder(arr, len);         // 单独測试可用(把数组进行排序。从小到大)switch_choice (arr, len);free(arr);return 0;
}void inputdata( int * arr, int len)
{int i;printf("please enter your data ;\n");for (i=0; i<len; ++i){printf("%d-->  ", i+1);scanf("%d", &arr[i]);}
}void arrangeinorder( int * arr, int len)
{int i,j,t;for (i=0; i<len; ++i){for (j=i+1; j<len; ++j){if (arr[i] > arr[j]){t = arr[i];arr[i] = arr[j];arr[j] = t;}}}resultdata(arr, len);
}void finddata( int * arr, int len)
{int n,i;int t = 0;printf("please enter the number you want to find\n");scanf("%d", &n);for (i=0; i<len; ++i){if (n == arr[i]){printf ("the number %d, is located in the %d th\n", n,i+1);t=1;}}if (t != 1 )printf("number %d is not in this array.\n", n);}void deletedata(int * arr, int * len)
{int n,i,j;int cnt =0;printf("please enter the number you want to delete from this array;\n");scanf ("%d", &n);for (i=0; i<*len; ++i){while(n == arr[i]){for (j=i; j<*len; ++j)arr[j] = arr[j+1];cnt++;   //to count amount of number had been delete from array.}}*len = *len - cnt;arr = (int*)realloc(arr, sizeof(int)*(*len));if( arr == NULL ){printf("realloc memory failed\n");exit(1);}resultdata(arr, *len);switch_choice (arr, * len);
}void adddata(int * arr, int * len)
{int n,i,j,k,t1;int *add,*tmp;int cnt =0;int t = 0;printf("please enter the amount of element you want to add;\n");scanf("%d", &n);add = (int *)malloc(sizeof(int) * n);inputdata(add, n); //把用户要加入的数据加入一个新的数组。t1 = *len; //以下循环实用,当用户输入的数都大于不论什么数的时候用的*len = *len + n ; //又一次定义下数组长度。依据用户要扩充的大小。

//realloc(arr, sizeof(int)*(*len)); tmp = (int*)realloc(arr, sizeof(int)*(*len)); if( tmp != NULL) { arr = tmp; tmp = NULL; } else { printf("realloc memory failed\n"); exit(1); } for (i=0; i<n; ++i) // i 循环是 循环要加入的数 { for (j=0; j<t1+i; ++j) // j循环 是循环原数组 { if ( add[i] < arr[j]) { for (k=j; k <= t1+i; ++k) { t = arr[k]; arr[k] = add[i]; add[i] = t; } cnt = 1; break; } cnt = 0; } if ( 0 == cnt) arr[t1+i]=add[i]; } if (add != NULL) { free(add); add = NULL; } resultdata(arr, *len); switch_choice (arr, * len); } void resultdata( int * arr, int len) { int i; printf("new array has been show below\n"); for ( i=0 ; i <len ; ++i) { printf("%d--> ", i+1); printf("%2d \n", arr[i]); } } void switch_choice(int * arr, int len) { int n; printf("type number to choose the function you are going to use:\n"); printf("1. activate number search.\n"); printf("2. delete number from this array. \n"); printf("3. add new numbers to this array. \n"); printf("4. exit this program. \n"); scanf("%d", &n); switch (n) { case 1: finddata (arr, len); break; case 2: deletedata (arr, &len); break; case 3: adddata ( arr, &len); break; case 4: return; break; } }

转载于:https://www.cnblogs.com/jzdwajue/p/7131593.html

realloc函数引发的慘案相关推荐

  1. 安全起见,小心使用C语言realloc()函数

    在C语言中,良好的编程习惯要求一个函数只做一件事,如果一个函数实现了若干功能,可以说基本是一个糟糕的设计. C语言 realloc() 函数位于 stdlib.h 头文件中,其原型为:     voi ...

  2. C中堆管理—浅谈malloc,free,calloc,realloc函数之间的区别

    2019独角兽企业重金招聘Python工程师标准>>> 在进行C/C++编程的时候,需要程序员对内存的了解比较好清楚,经常需要操作的内存可分为下面几个类别: 堆栈区(stack):由 ...

  3. realloc函数在使用上要注意什么问题

    realloc函数在使用上要注意什么问题 这个函数的作用是重新分配空间大小,返回的头指针不变,只是改变空间大小.既然是改变,就有变大.变小和为什么改变的问题.变大,要注意不能大到内存溢出:变小,那变小 ...

  4. calloc、malloc、realloc函数的区别及用法

    calloc.malloc.realloc函数的区别及用法! 三者都是分配内存,都是stdlib.h库里的函数,但是也存在一些差异. (1)malloc函数.其原型void *malloc(unsig ...

  5. 浅谈malloc,calloc,realloc函数之间的区别

    内存区域可以分为栈,堆,静态存储区和常量存储区.局部变量,函数形参,临时变量都是在栈上获得内存的,它们获取的方式都是由编译器自动执行的. C 标准函数库提供了许多函数来实现对堆上内存管理,其中包括:m ...

  6. C语言 realloc函数 带着内存游走的函数

    realloc函数 realloc函数,带着内存游走的函数. 该函数将 ptr 指向的内存大小修改为size.内存中的数据从开头到size保留不变. 如果size大于原内存大小,则多出的部分会被初始化 ...

  7. realloc函_[转载]realloc函数的使用及注意事项(转)

    原型:extern void *realloc(void *mem_address, unsigned int newsize); 用法:#include 功能:改变mem_address所指内存区域 ...

  8. c++ 栈中如何给string malloc空间_malloc,free,calloc,realloc函数

    malloc函数 原型:extern void* malloc(unsigned int size): 功能:动态分配内存: 注意:size仅仅为申请内存字节大小,与申请内存块中存储的数据类型无关,故 ...

  9. 由c#事件监听、回调函数引发观察者模式

    由c#事件监听.回调函数引发观察者模式 事件监听: C#中的事件,可以简单的理解为类或者对象发生了一件事,并且把这件事通知给了其他的类或者对象,其他的类或者对象可以根据事件的消息有所反应. 这非常类似 ...

最新文章

  1. 电子科技大学计算机学院保研夏令营,电子科技大学计算机科学与工程学院网络空间安全保研夏令营...
  2. 怎么把php查询到的值显示到下拉框中_RazorSQL for Mac(数据库工具查询)8.5.3
  3. 配置 aws cli_AWS CLI教程–如何安装,配置和使用AWS CLI了解您的资源环境
  4. tft_LCD一些引脚极性设置方法:vsync, hsync, VBLANK
  5. HDU1427 速算24点【DFS】
  6. 互联网+ 何人能挡?带着你的Code飞奔吧!
  7. nyoj 628 小媛在努力= =(水)
  8. 网页如何截屏长图:f12 Ctrl+Shift+p cap
  9. pytorch读取数据集(分类文件夹加载)—ImageFolder()
  10. Axure教程 原型设计工具Axure RP新手入门教程(一):基础
  11. #51CTO学院四周年# 感谢51CTO学院让我走出迷茫
  12. XCode 报错Thread 2:signal SIGABRT
  13. 从Spring源码探究AOP代码织入的过程
  14. 用MindMaster绘制思维导图
  15. 哪些机型适配了android11,coloros11适配机型_coloros11支持机型有哪些
  16. ZY Player 2.8.3 中文版 (全网视频播放器)
  17. python--if语句判断数字正负值
  18. 【Resnet】Resnet代码详解(图+代码)
  19. 一个机器人,主要由哪几部分组成?
  20. ElasticSearchTransportClient集成SearchGuard插件实现索引级别的权限管控

热门文章

  1. list转map stream_advancedday10可变参数不可变集合及Stream流
  2. 计算机在轻化工程中的应用,计算机在基础化学实验当中的应用
  3. oracle剩余月份计算,[HELP]如何计算两个日期之间的月份(非MONTHS_BETWEEN)?
  4. python中的float和eval_python中eval和float_python中eval与json.loads对json的处理
  5. 网络推广外包——网络推广外包专员面对外链发布更注重细节
  6. 开展企业网站建设如何做到保质保量?
  7. 七天快排优化真的存在!
  8. python处理文本文件 提取英文单词看成一个整体_任意一个英文的纯文本文件,统计其中的单词出现的个数(shell python 两种语言实现)...
  9. Oracle数据库在进程中是,由浅入深讲解Oracle数据库进程的相关概念
  10. 杰奇为什么只能用php5.2,杰奇2.2修改系统定义后,网站报错问题解决