在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];
}
舉一反三,在移動數組數據的過程中應當注意移動順序應和拷貝順序一致,若二者順序不一致,極有可能造成內存重疊的問題。