May 28,2008

[c/c++] 動態記憶體配置(realloc)與指標(pointer)

標真是一個讓人又愛又恨的東西,控制得好效能沒話說,控制得不好就不知道它會飄到哪兒去了。這次的問題是碰到realloc與pointer的互動問題。

參考:
realloc - C++ Reference
記憶體配置


由上面文章(記憶體配置),有一個特性必須注意的:realloc()會"重新"分配指定大小的記憶體區塊,並將原位址的內容複製到新的位址。所以假使你原本有用指標去指向realloc()之前的記憶體區塊,在realloc()過後原區塊的內容會自動被free()掉,而你的指標指向的東西就毫無意義可言了,下面舉個例子。

char *buffer = NULL;
char *ptr = NULL;
int size = 100;

buffer = (char *) realloc( buffer, size * sizeof(char)); // the same as malloc() now.
ptr = buffer;

//這時候我放東西進去buffer裡面,放著放著可能不夠用了,須重新配置buffer大小
size += size; // make size double.
buffer = (char *) realloc( buffer, size * sizeof(char));

//注意的是,這時候buffer所指道的記憶體位子已經跟ptr指到的地方不同了!!
//buffer指向重新配置出來的記憶體,只是內容跟原本一樣,而ptr的那塊被free()了
//假使後面對記憶體的操作多了,硬要使用ptr會跳出一堆莫名其妙的東西

建議假使你要動態改變您在程式中使用記憶體的大小時(承接上面作字串處理的例子),盡可能不要用pointer去記錄字串出現的位子,因為再重新realloc()之後您的指標會變得沒有意義,可考慮記錄offset的數值取代使用pointer,簡單例子如下:

int offset;  //其他變數承接上面的例子

scanf("%s", ptr);
offset = ptr - buffer;
ptr += strlen(ptr) + 1; // because of '\0'

size += size; // make size double.
buffer = (char *) realloc( buffer, size * sizeof(char));
printf("%s\n", buffer + offset); // 這時候offset就會變得有意義

不過realloc()對效能而言就是一個很大的傷害啦:P,需要花時間配置記憶體,又把原記憶體的內容複製過去,斟酌使用吧。

Technoratitechnorati tags: , , , , , , , ,


Posted by evilsmile at 樂多Roodo! │22:47 │回應(3)引用(0)Programming_程式語言
樂多分類:網路/3C 共同主題:C/C++ 工具:編輯本文
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/6102369
回應文章

COOL.....
我好像懂ㄝXD
Posted by EGG at July 19,2008 10:34

COOL.....
我好像懂ㄝXD
Posted by EGG at July 19,2008 10:34
哇! 其實你是資工系畢業的吧XDDD
Posted by evilsmile at July 19,2008 13:25