C語言 記憶體重疊

2021-08-09 21:57:30 字數 1681 閱讀 1298

記憶體重疊:

拷貝的目的位址在源位址範圍內。所謂記憶體重疊就是拷貝的目的位址和源位址有重疊。

在函式strcpy和函式memcpy都沒有對記憶體重疊做處理的,使用這兩個函式的時候只有程式設計師自己保證源位址和目標位址不重疊,或者使用memmove函式進行記憶體拷貝。

memmove函式對記憶體重疊做了處理。

面舉例乙個可能會發生記憶體重疊的問題:

有n個整數,使前面的各數順序向後移m個位置,最後m個數變成最前面的m個數。

問題分析:

假設arr為儲存n為1-10的十個整數的陣列,m=3,

思路為:

先將8910(最後m個數)儲存在另乙個臨時陣列中,再將1-7整體向右(後)移動3(m)位,最後將儲存後m個數的臨時陣列放到最前面。

我們期望實現的結果為89101234567,

我們在將1-7向後移動的過程中,可能會出現記憶體重疊問題:我們由左至右移動資料,m=3,我們arr[0]處的1移動到arr[0+3](arr[3])處,將arr[1]處的2移動到arr[1+3](即arr[4])處,依次類推向後移動,但是我們忽略掉了乙個問題,當我們在將arr[3]處的數移動到arr[6]處時,此時的arr[3]已被修改為了1,以此類推,移動完後的結果為:1231231,並不是我們期望的1234567.

這就是在移動的過程中發生了記憶體重疊問題。

解決方案:

如果拷貝的目的位址在源位址範圍內且是從低位址拷貝到高位址,那麼應從被拷貝的資料的最後一位倒著依次向後移,如果是從高位址向低位址拷貝,那麼應從被拷貝的資料的第一位順著依次向前移。

所以我們可以在拷貝的過程中從右至左的移動資料,arr[6]移動到arr[9],arr[5]移動到arr[8],arr[4]移動到arr[7]依次類推,移完整個陣列,在這樣的移動過程中即使之前的資料被覆蓋了也無妨,因為此時我們已經實現了原資料的移動。

#include

#include

void move(int *arr,int n,int m)

int *p = (int *)malloc(m*sizeof(int));//動態申請記憶體,儲存後m個數

int i;

for(i=0;i

for(i=n-m-1;i>=0;i--)//為防止記憶體重疊,從後開始移

for(i=0;i

free(p);//釋放動態記憶體

}void show(int *arr,int len)

printf("\n");

}int main()

;    show(arr,sizeof(arr)/sizeof(arr[0]));//列印移動前的資料

move(arr,sizeof(arr)/sizeof(arr[0]),3);

show(arr,sizeof(arr)/sizeof(arr[0]));//列印移動後的資料

return 0;

}

memcpy和memmov函式原型和區別

c語言記憶體重疊問題

c語言關鍵字,編譯器優化時使用,不要對編譯器撒謊,如果把乙個指標定義成restrict 編譯器會相信你,並對程式進行優化,如果出現記憶體重疊的問題,編譯器不會替你排查。memcpy 會有記憶體重疊的問題,memove 會提前幫你檢查是否有記憶體重疊的問題。visual studio 把函式和變數定義...

c語言學習之記憶體重疊

遇到這樣乙個問題,當陣列進行拷貝的時候,如果是在同乙個陣列內拷貝,就有可能出現記憶體重疊的問題,比如 includevoid copy int a,int b,int len b從開始複製len個數字到a int main copy arr 0 arr 3 7 4,5,6,7,8,9,10,8,9,...

C 學習之記憶體重疊

首先先說一下strcpy,流行的strcpy函式寫法是 char my strcpy char dst,const char src view plain copy 如果注意到 1,檢查指標有效性 2,返回目的指標des 3,源字串的末尾 0 需要拷貝。寫出上面實現函式就不在話下。然而這樣的實現沒有...