-4

sprintf を使用すると、「%x ....」のような余分な文字列が出力されます。

int main()
{   
    char *word_tmp = new char[0];
    char *word_all = new char[0];

    for(int i=0;i<5;i++)
    {
        sprintf(word_tmp, "\nNumber:%d, Good Good!", i);
        sprintf(word_all, "%s%s", word_all, word_tmp);   
    }

    std::cout<<word_all;
}

プログラムは正しく動作しますが、出力していない文字列を出力します。

4

3 に答える 3

3

配列の長さがゼロであるためword_tmp、 の最初の呼び出しの結果を保持するのに十分な大きさのバッファがなくsprintf()、バッファ オーバーランが発生します。したがって、この場合、 への最初の呼び出しの動作sprintf()は未定義です。

これとは別に、またはの呼び出しの結果として重複するオブジェクト間でコピーが行われた場合、結果は undefined になりsprintf()snprintf()ます。

delete[]最後に、で割り当てられた配列を呼び出さないため、関数がメモリ リークを起こしていますnew[]

std::ostringstreamタイプセーフな方法で達成しようとしていることを行うには、 を使用する必要があります (プログラムの最小限の修正を作成するという以前の試みで問題を発見したJames Kanzeの功績によるものです)。

#include <iostream>
#include <sstream>

int main()
{
    std::ostringstream ss;
    for (int i = 0; i < 5; i++)
    {
        ss << "Number: " << i << ", Good Good!" << std::endl;
    }

    std::cout << ss.str();
}

これが実際のです。

于 2013-03-31T11:00:34.900 に答える
0

まず、絶対に使いたくないでしょうsprintf。正しく使用することはほとんど不可能です。この場合、存在しないメモリに値を出力しているため、未定義の動作が発生します。new char[0](どのくらいのメモリが割り当てられると思いますか?. 2 番目sprintfの では、存在しないメモリからも入力しています。より未定義の動作であり、同じメモリから出力と入力を行っています (あると仮定して)これも未定義の動作です。

sprintf新しい配列を忘れてください:

std::string results;
for ( int i = 0; i != 5; ++ i ) {
    std::ostringstream s;
    s << "Number: " << i << " Good Good!\n";
    results += s.str();
}
std::cout << results;

(これがあなたがやろうとしていることだと思います。)

最後に 1 つ: 実際の問題になることはほとんどありませんが、標準では、テキスト ストリーム ( などstd::cout) への最後の文字出力は . である必要があり'\n'ます。

于 2013-03-31T11:15:34.570 に答える