realloc函数引发的惨案

帮别人调试个程序,程序的功能主要涉及动态数组,实现动态数组元素的添加,删除,查找,显示功能。但是在执行添加功能的时候,连续执行三次添加的时候就会出现问题,让人感到非常的莫名其妙。

realloc函数引发的惨案_第1张图片

涉及到的函数如下所示:

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

从这里可以看到这段程序的缺点:

<1>全局变量的滥用,不过这里没有造成错误

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

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

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

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

但是第一次释放add就会出现下面的问题,执行调试,发现是在free的时候出现了问题,也就是free竟然失败了。

realloc函数引发的惨案_第2张图片

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 
#include 

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
执行结果:

realloc函数引发的惨案_第3张图片

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

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

#include 
#include 

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  ", i+1);
		scanf("%d", &arr[i]);
	}
}

void arrangeinorder( int * arr, int len)
{
	int i,j,t;
	for (i=0; 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  ", 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;
	}
}




你可能感兴趣的:(C,编程,malloc,realloc,free失败)