1

そのため、今日、コンストラクターの引数リストにNULLが渡され、アプリケーションが破損するというバグに遭遇しました。コンパイラがこれを禁止しなかったのは奇妙なことです。引数リストが変わったので、今まで気づかなかった。次のコードスニペットを参照してください。

このオブジェクトは3つのパラメーターを取ります。std::string&に細心の注意を払ってください。

class Foo {
public: 
    std::string myName;
    unsigned int someVariable;
    void * ptr;

    Foo(const std::string&  name, void * aPtr, unsigned int variable);
    ~Foo();
}

Foo::Foo(const std::string&  name, void * aPtr, unsigned int variable) : myName(name), ptr(aPtr), someVariable(variable)
{
   // object constructed
}


int main(int argc, char* argv[])
{
   // construct an instance of Foo
   Foo foo(NULL /*whoops, passed in NULL when a string should be passed in*/,
           "foo", 
           0);   // program compiles as expected, A NULL pointer runtime error occurs when executed.
}

したがって、基本的に、fooオブジェクトの入力値を誤って切り替えた場合、コンパイラは何もしません。アラームは鳴らず、プログラムがクラッシュしたときに何が起こったのか頭を悩ませたままになります。これを防ぐ方法があるはずだと思います。この問題を回避する何かがありますか?コンパイラにオンにする必要があるものはありますか?

4

2 に答える 2

8

実際にNULLは、参照によって渡されているわけではありません。

std::stringを取る変換コンストラクターがありchar const*ます。 NULLは null ポインター定数であるため、achar const*が期待される場所で使用できるため、std::stringこの null ポインターからオブジェクトが構築されます。この構造は、未定義の動作をもたらします。

ユーザーにより良い警告を提供する 1 つのオプションは、char const*パラメーターを持つ別のコンストラクターを追加することです。このようにして、null が渡された場合にコンストラクターに assert を簡単に追加できます。これはコンパイル時のチェックではありませんが、この問題に頻繁に遭遇する場合は、何もしないよりはましかもしれません (その価値のために、思い出すことはできません)。この問題に遭遇したことがないので、努力する価値はないと私は主張します)。

于 2012-07-31T22:19:54.887 に答える
1

これは私がすることです:

    Foo(const std::string&  name, void * aPtr, unsigned int variable);
    ~Foo();
private:
    Foo(int, void*, unsigned int); // Do not implement.
                                   // This will generate a link time error when
                                   // NULL is used as the first parameter.

注: この変更を行わなくてもコンパイラ エラーが発生します (したがって、これは明らかに実行中のコードではありません)。しかし、明らかな間違いを修正しても、次のようになります。

n.cpp:27: error: invalid conversion from ‘const void*’ to ‘void*’
// This is caused by the parameter -> "foo"
于 2012-07-31T22:48:41.357 に答える