2010-02-09 134 views
0

我的代碼如下:段錯誤拷貝構造函數

void Scene::copy(Scene const & source)  
{ 
maxnum=source.maxnum; 
imagelist = new Image*[maxnum]; 

for(int i=0; i<maxnum; i++) 
{ 
    if(source.imagelist[i] != NULL) 
    { 
    imagelist[i] = new Image; 
    imagelist[i]->xcoord = source.imagelist[i]->xcoord; 
    imagelist[i]->ycoord = source.imagelist[i]->ycoord; 
    (*imagelist[i])=(*source.imagelist[i]); 
    } 

    else 
    { 
    imagelist[i] = NULL; 
    } 
} 
} 

一點背景:Scene類有一個私人詮釋稱爲MAXNUM並在施工圖像指針的動態分配的數組。這些指針指向圖像。複製構造函數試圖對數組中的所有圖像進行深層複製。不知何故,我得到一個Segfault,但我不明白我將如何訪問數組越界。

任何人都看到什麼了嗎?

我是新的C++,所以它可能是一些明顯。

感謝,

回答

0

我建議MAXNUM(也許圖像列表)成爲私有數據成員和實施const getMaxnum()setMaxnum()方法。但我懷疑這是你描述這種方式的任何段錯誤的原因。

我會嘗試你參考之前去除常量和落實常量公共方法來提取數據。它可能編譯,因爲它只是一個參考。另外,我會嘗試切換到一個指針,而不是通過引用傳遞。

或者,可以創建一個單獨的場景類對象,並通過圖像類型數據作爲數組的指針。我不認爲你可以聲明Image *imagelist[value];

void Scene::copy(Image *sourceimagelist, int sourcemaxnum) { 
maxnum=sourcemaxnum; 
imagelist=new Image[maxnum]; 
//... 
    imagelist[i].xcoord = sourceimagelist[i].xcoord; 
    imagelist[i].ycoord = sourceimagelist[i].ycoord; 
//... 
} 
//... 
Scene a,b; 
//... 
b.Copy(a.imagelist,a.maxnum); 
0

如果源圖像具有比MAXNUM在其圖像列表項的實際數目設定得較高,則環路將運行經過source.imagelist數組的末尾。也許當陣列開始是空的(或MAXNUM可能不會得到根本initalized),或者也許如果你有一個場景:: remove_image()函數MAXNUM是越來越初始化爲一個,它可能已經刪除的圖像列表條目不遞減MAXNUM。我建議使用std :: vector而不是原始數組。該向量將跟蹤自己的大小,因此您的for循環將是:

for(int i=0; i<source.imagelist.size(); i++) 

它只會訪問與源矢量保持一樣多的項目。崩潰的另一種可能的解釋是,source.imagelist中的一個指針屬於被刪除的映像,但指針從未設置爲NULL,並且現在是一個懸掛指針。

delete source.imagelist[4]; 
... 
... // If source.imagelist[4] wasn't set to NULL or removed from the array, 
... // then we'll have trouble later. 
... 
for(int i=0; i<maxnum; i++) 
{ 
    if (source.imagelist[i] != NULL) // This evaluates to true even when i == 4 
    { 
     // When i == 4, we're reading the xcoord member from an Image 
     // object that no longer exists. 
     imagelist[i]->xcoord = source.imagelist[i]->xcoord; 

最後一行將訪問它不應該訪問的內存。也許對象仍然存在於內存中,因爲它還沒有被覆蓋,或者它可能被覆蓋,並且您將檢索到無效的xcoord值。如果你幸運的話,那麼你的程序就會崩潰。如果您直接處理新建和刪除操作,請確保在刪除指針後將其指針設置爲NULL,以便您沒有懸掛指針。但是,如果您在某個地方持有指針的副本,則不會阻止此問題,但在這種情況下,當您刪除並將NULL複製到第一個副本時,第二個副本不會設置爲NULL。如果以後嘗試訪問指針的第二個副本,則無法知道它不再指向有效的對象。

它是更安全使用智能指針類,並讓這種處理內存管理你。標準C++庫中有一個名爲std :: auto_ptr的智能指針,但它具有奇怪的語義,不能在C++容器中使用,如std :: vector。但是,如果你安裝了Boost庫,那麼我建議用boost :: shared_ptr替換原始指針。