2012-05-28 101 views
0

我有一個像陣列雙打和堆損壞

template <class Type> 
myFunc(Type** arrayToBeFilled); 

函數我這樣稱呼它:

double* array = NULL; 
myFunc(&array); 

我做一些閱讀和分析數字與strtod轉換函數的函數裏面:

//打開文件,獲取每行的行數和雙打數

... 
    char *inputString = new char[LONG_STRING_SIZE]; 
    char *pNext = NULL; 
    (*arrayToBeFilled) = new Type[length*rowSize]; 

for (int i=0; i<length; i++) 
    { 
     source.getline(inputString, LONG_STRING_SIZE); 
     pNext = NULL; 

    for (int j=0; j<rowSize; j++) 
    { 
     double d = strtod(inputString, &pNext); 
     (*arrayToBeFilled)[i*rowSize+j] = d; 
     inputString = pNext; 
     pNext = NULL; 
    } 
    } 

變量d只是用於調試器的檢查 - 而且它在運行時很好。 但是填充數組後,我嘗試打印它(只是爲了檢查)

for (int i=0; i<length; i++) 

    { 
     for (int j=0; j<rowSize; j++) 
      { 
       cout<<(*arrayToBeFilled)[i*rowSize+j]<<" "; 
      } 
     cout<<"\n"; 
    } 

這裏來壞輸出 - 其他號碼,有時堆腐敗等。我正在打印和退出該功能 - 相同的結果。而且我不能刪除這個數組,否則都不會出現這個函數 - 運行時錯誤跟着我!

+1

您發佈的代碼看起來不錯 - 問題可能出現在您未發佈的代碼中。你能發佈一個完整的例子來產生錯誤嗎? – HighCommander4

+0

不應該是我*長度(因爲你正在迭代長度)+ j? –

+0

@KamilKlimek:沒有。考慮'i'作爲跳過的行數以到達當前行的開始位置。因此,跳過的*元素*的數量是'i * rowSize'。 – HighCommander4

回答

2

爲什麼在C++中使用原始C數組?如果您使用STL類std::vector而不是原始new[],那麼您的代碼將變得更清晰,更易於閱讀和維護(例如,您不需要明確的delete[]調用:析構函數將清理堆內存)。一般來說,在現代C++中,如果您正在編寫新的或刪除的規則,則該規則爲「」,但您做錯了「(有一些例外)。

還要注意與C++ 11移動語義,你可以簡單地返回vector而不是使用輸出參考/指針參數:

template <typename Type> 
inline std::vector<Type> myFunc() 
{ 
    ... 
} 

你的函數體內部,而不是你的代碼

(*arrayToBeFilled) = new Type[length*rowSize]; 

只是寫:

std::vector<Type> arrayToBeFilled(length*rowSize); 

,然後只需return arrayToBeFilled;

(還要注意的是vector的可以被嵌套在一起:你也可以使用vector<vector<Type>>,使二維數組,但是這比單個vector<Type>,可以更直接地映射到您的原始new[]通話效率較低。)

此外,在您發佈的代碼中,您在堆上創建一個原始C數組,並將它指向inputString;那麼你可以使用pNext中的一個賦值來修改inputString:但是這樣做會泄漏指針存儲在inputString中的初始數組。

+0

100%正確,但我測試了使用原始數組和向量的迭代,並且使用最大優化數組更好。所以我試着熟悉他們的表演。 –

+0

如果您正在使用Visual C++,是否比較了_release_構建中的性能(在調試版本中是否有額外的機制來檢測緩衝區溢出,無效的迭代器等,這些有助於調試但會導致開銷)? – 2012-05-28 14:59:53

+0

不,測試是爲了調試。也會測試發佈,謝謝! –

1

看來你沒有返回類型

template <class Type> 
void myFunc(Type** arrayToBeFilled); 

,你應該初始化函數

double array = NULL; 
myFunc<double>(&array); 

也當談到輸入,打印出你的價值,更多的時候比不會,你可能會得到意想不到的事情導致錯誤。