2016-07-30 4 views
0

環境を反復した後に:Windows 7のプロのx64、マイクロソフトのVisual Studio 2015のEnterprise、バージョン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

私は大好きですが、sto :: stringで動作しない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

はい、このアプローチは、ポインタのコピーを作成してそれを反復して元のコードブロックを削除する2番目のコードブロックになる可能性があります。 – Zyre

+0

エラーは、削除から来ています 私はいつもあなたが今どこにいるので、私の目のインデックスでイテレーションが簡単になります。 実際のコードはループしていますか?それとも、本当に一歩進んだのですか? –

+0

もう1つのコメントとして、std :: stringを使用してください(可能な場合)。同様の変換機能もあります:http://www.cplusplus.com/reference/string/、ストーリーから整数への変換 –

0

私はポインタを反復処理することができますし、私はそれらと一緒に行う必要があることを終えたら、正しく削除してください。

ポインタのコピーを作成します。

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

Aは、おそらくより一般的なイディオムは一時的なデリファレンスにある:

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

私は[使用std::stringに大好きです]しかし、私はstd :: stringで動作しませんatoi()を使用する必要があります

あなたは間違っています。 atoistd::stringと同じです。 strcpyと同じように、単にstd::string::c_str()を使用してください。 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); 

あなたの間違いは、元のポインタの代わりにシフトポインタを削除しようとしています。その結果、ヒープマネージャーは割り当てられたブロック情報を間違って取得し、通常は割り当てられたポインターの前に置かれ、ヒープの破損が発生します。

関連する問題