2016-07-30 63 views
0

環境後:視窗7親64,微軟的Visual Studio 2015企業版本14.0.25424.00更新3C++上刪除錯誤[]通過指針迭代

int testFunction() 
{ 
    std::string _orig = "[188 80% (1/2)O:152]"; 
    std::string _orig2 = "[999 99% (1/1)O:999]"; 

    char *orig = NULL; 
    char *orig2 = NULL; 

    orig = new char[_orig.length() + 1]; 
    strcpy(orig, _orig.c_str()); 

    orig2 = new char[_orig2.length() + 1]; 
    strcpy(orig2, _orig2.c_str()); 

    *orig++; 
    *orig2++; 

    int a = atoi(orig); 
    int b = atoi(orig2); 

    delete[] orig; 
    delete[] orig2; 

    return 0; 
} 

運行上面代碼崩潰與「_CrtIsValidHeapPointer(塊)「錯誤。

如果我不迭代(* orig ++和* orig2 ++),那麼沒有問題。

所以我的問題是,我怎樣才能遍歷指針,然後當我做完我需要做的與他們,刪除[]他們正確?

+0

爲什麼要使用'char'指針?整個使用'std :: string'。 –

+0

我很想,但我需要使用atoi(),它不會在標準::字符串上工作 – Zyre

+2

(1)爲什麼你需要它?有C++等價物。 (2)你* *實際上可以將'std :: string'中的指針傳遞給'atoi'就好了:'atoi(str.c_str())'起作用。 –

回答

2

你沒有刪除你分配的指針!

delete必須在由new返回的原始存儲器地址上調用。既然你做了orig++,你不能指定delete的地址!

迭代可以用指數來完成,並使用數組訂閱取消引用:

orig[i] = 'a'; 

這是一樣的這樣做:

*(orig+i) = 'a'; 

或者你可以得到另一個指針到同一數據,並修改這一個。

char* pOrig = orig; 
++pOrig; 

你爲什麼寫

*orig++; // why dereferencing? 

本身就++會做迭代。

+0

是的,這種方法很可能是您的第二個代碼塊,您可以在其中創建指針副本並遍歷該指針,然後刪除原始代碼塊。 – Zyre

+0

錯誤來自刪除, 我眼中的指數更容易迭代,因爲你總是現在在哪裏你atm。 您的循環是否是真正的代碼?或者你真的只是在那裏一步? –

+0

作爲另一個評論提到,使用std :: string(如果可能)。還有轉換功能:http://www.cplusplus.com/reference/string/,例如用於字符串到整數轉換的stoi –

0

我該如何迭代指針,然後當我完成我需要做的事情時,正確刪除[]它們?

創建的指針的副本:

char* orig = new char[size]; 
char* i = orig; 
*i++ = 'a'; 
delete orig; 

一個也許更常見的成語是取消引用一個臨時的:

for(int i = 0; i < size - 1; i++) 
    orig[i] = 'a'; 

我很想[使用std::string ],但我需要使用atoi(),它不會在std :: string上工作

你錯了。 atoi只適用於std::string。只需使用std::string::c_str(),就像您使用strcpy一樣。絕對沒有理由用new分配一塊內存。

+0

是的,這也是我要去的方式,但不知道這是最好的方法。我很高興你提到/確認了它。謝謝。 – Zyre

0
int testFunction() 
{ 
    std::string _orig = "[188 80% (1/2)O:152]"; 

    int a = 0; 
    for (std::string::iterator it = _orig.begin(); it != _orig.end(); ++it) 
    { 
     if (isdigit((char)*it)) 
      a = (atoi(it._Ptr)); 
    } 

    return 0; 
} 

我明白了。感謝幫助我得出這個結論的每個人。事實上,保持std :: string是最好的方法。

2

避免使用原始指針。您的代碼可以更簡單:

std::string orig = "[188 80% (1/2)O:152]"; 
std::string orig2 = "[999 99% (1/1)O:999]"; 

int a = atoi(orig.c_str() + 1); 
int b = atoi(orig2.c_str() + 1); 

你的錯誤是,試圖刪除移動指針而不是原來的指針。由於堆管理器通常在分配的指針之前得到了錯誤的分配塊信息,並且你得到了堆損壞。