在C语言中使用数组不仅要注意数组越界的问题,还有一种关于内存的问题应当注意,内存覆盖。
谭浩强的《C程序设计》中有一道移动数组中元素的题目:
经简单分析,需动态申请一段长度为m的内存记录数据,再将该数组中前n-m个数据后移,之后将动态内存中的数据赋值到新数组中。代码实现如下:
//int arr[] = {1,2,3,4,5,6,7,8,9,10};
//m = 3;
void MyMove(int *arr,int n,int m)
{
int *brr = (int*)malloc(m*sizeof(int));
for(int k=0; k<m; k++)//拷贝后m个数据
{
brr[k] = arr[k+n-m];
}
for(int i=0; i<n-m;i++)//数组arr中的数据后移
{
arr[i+m] = arr[i];
}
for(int j=0; j<m;j++)//将动态内存中的数据拷贝arr前m个
{
arr[j] = brr[j];
}
free(brr);
brr = NULL;
}
此时虽然编译通过,但是运行程序却得到了错误的结果。
在调试过程中,发现移动过程中存在内存重叠的问题,即在此问题到第四个数据时原数组的数值已经开始被改变,导致了错误的结果。
为保证拷贝过程中不会改变原数组的数据,从第n个数据开始拷贝,到第m-1个数据结束。
//数组arr中的数据后移,从后往前开始
for(int i=n-1; i>=m;i--)
{
arr[i] = arr[i-m];
}
举一反三,在移动数组数据的过程中应当注意移动顺序应和拷贝顺序一致,若二者顺序不一致,极有可能造成内存重叠的问题。