2013-10-16 71 views
2

我覺得我錯過了一些明顯的東西,我無法弄清楚。 基本上,似乎信息正確存儲在第一個for循環。但是當我在第二個循環打印出它的唯一垃圾值時。我錯過了什麼?我是比較新的這個用於陣列的C++動態內存分配

bignum::bignum(const string &digits) 
{ 
    int length = digits.length(); 
    ndigits = 0;  

    for (int i = 0; i < length; i++) 
    { 
     if(isdigit(digits[i])) 
     { 
      ndigits++; 
      digit = new int[ndigits]; 
      int tmpInt = digits[i] - '0'; 
      digit[i] = tmpInt; 
     } 
     if(isalpha(digits[i])) 
     { 
      break; 
     } 
     cout <<"step "<< i << " " << digit[i] << endl; 
    } 

    for (int i = 0; i < ndigits; i++) 
    { 
     cout << digit[i] << " "; 
    } 
    cout << endl; 
    cout << "digits" << ndigits << endl; 
    cout << endl; 
} 
+6

你正在像瘋了一樣泄漏內存。 – chris

+0

@chris我有一個數字陣列的析構函數 – Chase

+2

沒關係,你根據條件在循環內調用'new'。我看不出每個'new []'調用如何調用delete []'。 – juanchopanza

回答

4

要動態分配每次isdigit(digits[i])條件truedigit。 因此,只要您找到一位數字,就會再次爲digit分配內存,並且關於以前的數字的信息將丟失。此外,還有內存泄漏。

您應該在for循環開始前分配digit一次,並計算您找到的位數並將找到的數字存儲在digit中。

此外,每當您完成任何動態分配的內存時,您都應該釋放所有動態分配的內存,以便它可以重複使用。

+0

也應該考慮不要直接使用動態分配的內存,但可以使用例如一個向量或智能指針代替:) – codeling

+0

@nyarlathotep是的,確實 – Kunal

+0

@nyarlathotep相信我我會使用矢量,如果我可以但這是一個類,它需要動態分配的數組。 – Chase

1

假設你不想使用集合,因爲你正在完成學習練習,這裏是你應該記住的:當你動態地創建一個數組時,最好找出它將會有多少元素先分配一次,填充數據,使用它,然後取消分配結果。

爲了這個工作,你需要將你的第一個循環分成兩個循環 - 一個用來計算數字,另一個用你找到的數字填充數組。分配應在第一循環之後和第二循環開始前發生:如果你想爲你獲得更多的數字被調整陣列

ndigits = 0;  
// First, you need to count the digits 
for (int i = 0; i < length; i++) 
{ 
    if(isdigit(digits[i])) 
    { 
     ndigits++; 
    } 
    if(isalpha(digits[i])) 
    { 
     break; 
    } 
} 
// Next, allocate the array for your digits 
int *digit = new int[ndigits]; 
int *dp = digit; 
// Now go through the string again, and add digits to the newly allocated array 
for (int i = 0; i < length; i++) 
{ 
    if(isdigit(digits[i])) 
    { 
     (*dp++) = (digits[i] - '0'); 
    } 
    if(isalpha(digits[i])) 
    { 
     break; 
    } 
} 
... // Use your digit[] array here... 
// Once you are done, free the array 
delete[] digit; 
0

試試這個。這個版本最初有10個空間,當11號出現時增加10個大小等等。新陣列被創建,並且舊數據被複制到它。舊的數字數組被刪除,然後它的指針被替換爲新版本。

這種方法在某些情況下可能會很慢(因爲當舊的已滿時複製到新的更大),但如果您通常少於10位數,應該可以。如果您通常超過10個,請使用較大的初始數字。

int digits_max = 10; 
int digits_pos = 0; 
int *digit = new int[digits_max]; 

...

if(isdigit(digits[i])) { 
    if (digits_pos == digits_max) { 
     int new_max = digits_max + 10; 
     int *digit_tmp = new int[new_max]; 

     // Copy from old array to new 
     for (int i = 0; i < digits_max; i++) { 
      digit_tmp[i] = digit[i]; 
     } 

     delete[] digit; // Free old memory, or your RAM gets full 

     digit = digit_tmp; 
     digits_max = new_max; 
    } 
} 
else { // Always break if not int 
    break; 
} 

int tmpInt = digits[i] - '0'; 
digit[digits_pos] = tmpInt; 
digits_pos++; 

退出之前(或當您使用數字陣列完成),應該將其刪除:

delete[] digit; 

編輯:移到digits_pos ++結束的循環,最後的版本是錯誤的。