0

次のコードが 26 timez 'Z' の代わりに 'A' から 'Z' の範囲を出力する理由と、この配列を正しく出力するにはどうすればよいかを誰かが説明できますか? コードを見てください:

wchar_t *allDrvs[26];
    int count = 0;
     for (int n=0; n<26; n++)
     {
         wchar_t t[] = {L'A' + n, '\0'}; 
         allDrvs[n] = t;
         count++;
     }
     int j;
     for(j = 0; j < count; j++)
     {
        std::wcout << allDrvs[j] << std::endl;
     }
4

3 に答える 3

5

問題 (少なくとも 1 つ) は次のとおりです。

{
     wchar_t t[] = {L'A' + n, '\0'}; 
     allDrvs[n] = t;  //allDrvs points to t
     count++;         
 }   //t is deallocated here
     //allDrvs[n] is a dangling pointer

つまり、短い答え - 行での未定義の動作std::wcout << allDrvs[j]

正しい出力を得るには - があります安っぽい動的割り当てと配列間のコピーを含む醜いバージョン。

次に、を使用する正しいバージョンがありstd::vector<std::wstring> >ます。

于 2012-10-23T14:24:41.437 に答える
0

あなたのコードには未定義の動作があります。自動t保存期間があるため、上のループを終了するとすぐに存在しなくなります。YourallDrvsには、2 番目のループで使用するまでに破棄されたオブジェクトへの 26 個のポインターが含まれています。

たまたま、(実行している状況、使用しているコンパイラなどで)tループの繰り返しのために同じストレージスペースを再利用しているように見えます。 allDrvs2 番目のループで使用すると、そのストレージは上書きされていないため、同じデータへの 26 個のポインターがあります。

とにかくC++を使用しているのでstd::wstring、おそらくstd::vector代わりに and を使用することをお勧めします-たとえば、この一般的な順序で何か:

std::vector<std::wstring> allDrvs;

for (char i=L'A'; i<L'Z'; i++)
     allDrvs.push_back(std::wstring(i));

技術的には、これは完全に移植可能というわけではありません。連続していることに依存します'A' .. 'Z'。これは、すべての文字セットに当てはまるわけではありません。IBM の EBCDIC は明らかな例外です。その場合でも、すべての適切な出力が生成されますが、実際には必要のないいくつかの追加項目も含まれます。

とはいえ、オリジナルは連続していることに依存し'A'..'Z'ており、コードはとにかく Windows を対象としているように見えるので、おそらく大きな問題にはなりません。

于 2012-10-23T14:29:37.810 に答える
0

あなたt[]はスタックにあります。一度にループの 1 つの反復に対してのみ存在し、次の反復はそのスペースを再利用しているように見えます - 必要な動作ではありませんが、これは結果に基づいて起こっているようです。最初のループが完了した後にデバッガーで調べるallDrvs[]と、おそらくすべてのポインターが同じメモリ位置を指していることがわかります。

これを解決するにはさまざまな方法があります。tループの反復ごとにヒープに新しいものを割り当てることができます (後で削除します)。wchar_t allDrvs[26][2];の代わりに を実行して、反復ごとwchar_t *allDrvs[26]に の内容をコピーできます。後で行うのではなく、最初のループですぐにt表示できます。配列やポインターを使用する代わりに、 andをt使用して物事を管理できます。std::vectorstd::wstring

于 2012-10-23T14:28:42.887 に答える