2010-10-06 58 views
10

在早先的問題,我問類型轉換指針,但被引導到使用C++分配系統代替mallocs的更好的解決方案。 (我把一些C代碼C++)更換的realloc(C - > C++)

然而,我仍然有類似功能的問題:

我改變:

tmp = malloc(sizeof(char*) * mtmp); --> tmp = new char*[mtmp]; 

free(tmp) --> delete [] tmp; 

然而,我該怎麼做的realloc在以下功能:

char* space_getRndPlanet (void) 
{ 
    int i,j; 
    char **tmp; 
    int ntmp; 
    int mtmp; 
    char *res; 

    ntmp = 0; 
    mtmp = CHUNK_SIZE; 
    //tmp = malloc(sizeof(char*) * mtmp); <-- replaced with line below 
    tmp = new char*[mtmp]; 
    for (i=0; i<systems_nstack; i++) 
     for (j=0; j<systems_stack[i].nplanets; j++) { 
     if(systems_stack[i].planets[j]->real == ASSET_REAL) { 
      ntmp++; 
      if (ntmp > mtmp) { /* need more space */ 
       mtmp += CHUNK_SIZE; 
       tmp = realloc(tmp, sizeof(char*) * mtmp); <--- Realloc 
      } 
      tmp[ntmp-1] = systems_stack[i].planets[j]->name; 

我收到以下錯誤:

error: invalid conversion from 'void*' to 'char**'| 

編輯2:

好吧,我得到的共識是,我要拋棄我目前的解決方案(這我公開這樣做)。

只是爲了確保我的理解正確,你們是否意味着,而不是一個指向對象的指針數組,我應該只有一個包含對象本身的向量?

+1

那麼忽略)不正確地在上述片的代碼的事實,你正在使用的realloc(。這是C++造成的一個弱點,因爲對象具有構造函數/析構函數。該問題通過使用矢量而不是原始數組來解決。 – 2010-10-06 03:02:12

回答

14

C允許void*被隱式轉換爲任何指針。 C++不會,所以如果您使用的是realloc,則必須將結果轉換爲適當的類型。

但更重要的是,在由new[]返回的指針上使用realloc是未定義的行爲。並沒有直接的C++風格相當於realloc

你的選擇是,從最低到最高地道:

  • 玉碎malloc/realloc/free投下的指針。
  • 使用new[] + delete[]而不是realloc
  • ,而不是管理自己的內存使用std::vector<std::string>
+1

另外你不應該混合new/delete和malloc/calloc/realloc/free內存分配。 – PaulMcG 2010-10-06 06:00:55

+1

從技術上講,你應該使用'delete []'用'new []'。 – Derek 2013-05-23 13:23:17

2

http://www.cplusplus.com/forum/general/18311/

(簡而言之 - 有沒有一個真正的C++相當於realloc,但也許你會使用vector的更好?)

+0

你能向我解釋一下realloc在這裏做什麼?另外,通過用矢量替換當前的解決方案,這是否意味着,我使用的是類似數組的設備(即矢量),而不是堆棧。 I.e .:這是否意味着我應該更換當前的堆棧解決方案? – Biosci3c 2010-10-06 02:58:58

+0

@ Biosci3c您也可以使用堆棧。 C++在標準模板庫中定義了這兩種類型。請參閱http://www.cplusplus。com/reference/stl/ – zneak 2010-10-06 03:02:05

+1

@ Biosci3c - realloc正在創建一個更大的內存空間來容納'tmp'中的內容,因爲舊空間已經滿了。可重新定義的C++容器爲你自動執行此操作。你可以使用'stack'或'vector';他們都支持「類似堆棧」的操作(但「vector」也支持隨機訪問,而「stack」則不支持)。 – Amber 2010-10-06 03:05:55

-1

目前的realloc沒有C++當量()。

最佳使用:

char* new_tmp = new (char*)[mtmp]; 
for (int n=0;n<min(mtmp,oldSize);n++) new_tmp[n] = tmp[n]; 
delete [] tmp; // free up tmp 
tmp = new_tmp; 

你所得到的錯誤是因爲C++是隱式類型鑄造少寬鬆。

+1

不是最好的使用 - 「realloc」的想法是保留內存內容。 – 2010-10-06 02:59:20

+1

如果你堅持做手動內存分配,你應該分配新的內存,然後將內容複製到新分配的內存。只有在兩者都成功後,才能刪除舊的內存。 – 2010-10-06 03:32:32

1

不幸的是C中沒有realloc ++(由於內存可能持有的非平凡構造或只是不可複製的對象)。要麼分配新的緩衝區和複製或學習使用std::vectorstd::stack會自動爲你做這個。

13

這似乎是一個根據需要增長的不起眼的數組。

停止使用明確的內存分配,你幾乎可以肯定用不着它。使用std::vector或另一個C++標準庫的動態容器,可根據需要自動增長。

它也像你使用空終止的C風格的字符串。爲什麼不用std::string代替?

+0

我正在轉換一些舊的C代碼,並隨着我的學習(不太熟悉C,只是C++)。所以這可能會奏效。 – Biosci3c 2010-10-06 03:00:55

2

realloc的犯規reallly關心調用構造函數,因此,使用新的realloc似乎像一個壞idea.You應該去爲載體作爲一個更好的辦法了。您可以調整矢量大小。

5

在C++中,不應該使用陣列(甚至動態分配)。

這已被替換的std ::矢量

在C:

char** tmp = (char**)malloc(sizeof(char*) * size); 
free(tmp); 

// And a correct version of realloc 
char** alt = (char**)realloc(sizeof(char*) * newSize); 
if (alt) 
{ 
    // Note if realloc() fails then it returns NULL 
    // But that does not mean the original object is deallocated. 
    tmp = alt; 
} 

在C++

std::vector<char*> tmp(size); 

// No need for free (destructor does that). 
tmp.resize(newSize); 
1

我會考慮從手工製作的動態陣列切換到矢量是一個很好的首選。

至於矢量是否應該直接包含的對象,或包含指向實際的對象,沒有一個明確的答案 - 這取決於許多因素。

最大的單一因素是是否這些我稱之爲「實體」的對象 - 那些爲其複製是沒有意義的。一個典型的例子就像iostream或網絡連接。通常沒有合理的方法來複制或分配像這樣的對象。如果那是你正在處理的那種對象,那麼你幾乎堅持存儲指針。

但是,如果你處理什麼一般(寬鬆)定義爲「值對象」,複製和分配將被罰款,並直接在矢量存儲的對象將被罰款。對於這樣的對象,存儲指針的主要原因是,向量可以/將在需要擴展內存以爲更多對象騰出空間時複製對象。如果你的對象如此龐大而且昂貴以至於不能被複制,那麼你可能想要在向量中存儲類似指針的東西來獲得便宜的複製和分配。機會是,將是原始指針雖然 - 它可能會是某種智能指針對象提供更多的價值,像這樣的語義大多數其他代碼可以把對象作爲一個簡單的值,並且細節其昂貴的操作等可以保持隱藏。