0

関数のループで一時変数 (「new」ではなく char * など) を初期化した場合、明示的に解放する必要がありますか? 後者は私が教えられたことです...Valgrindを介してコードを実行すると、「15バイトが確実に失われます」が、上記のような領域にあるようです...範囲外の一時変数。これらは「新規」で割り当てられたものではありません... Valgrind は、コードの外観に基づいていくつかの数値を取得しますか、それとも実際に孤立したメモリをキャッチしていますか? Valgrind を使用する場合、ほとんどの人はいくつかの小さな数字が失われることを期待していますか、それとも 0 バイトがゲームの名前を失っているのでしょうか? みんなありがとう。

==7669== 15 bytes in 1 blocks are definitely lost in loss record 1 of 1                    │        std::cout << "    ...printing newly initia
==7669==    at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memc│lized customer..." << std::endl;                  
heck-x86-linux.so)                                                                         │        if (true)                                 
==7669==    by 0x8049C4B: Customer::copyString(char const*&, char*&) (customer.cpp:539)    │        {                                         
==7669==    by 0x804992A: Customer::getName(char*&) (customer.cpp:379)                     │                const char * name = "bunches, oate
==7669==    by 0x8048C2D: main (main.cpp:78)                                               │s";                                               
==7669==                                                                                   │                Customer cus5(name);              
==7669== LEAK SUMMARY:                                                                     │                cus4 = cus5;                      
==7669==    definitely lost: 15 bytes in 1 blocks                                          │        }                                         
==7669==    indirectly lost: 0 bytes in 0 blocks                                           │                                                  
==7669==      possibly lost: 0 bytes in 0 blocks                                           │        cus4.displayData();                       
==7669==    still reachable: 0 bytes in 0 blocks                                           │        std::cout << std::endl;                   
==7669==         suppressed: 0 bytes in 0 blocks  

「copyString()」メソッドと「getName()」メソッドの両方に一時変数しかありません...他のすべては解放されます...「main.cpp」には解放していないメモリがありますが、それは私のテスト用ハーネスです現時点では、それをきれいにすることについてあまり心配していません。Valgrind によってリストされているもの (copyString、getName、main の 3 行など) は、メモリが確実に失われていることを意味しますか?

これは「getName()」関数です。

int Customer::getName(char *& toReturn)
{
        if (name)
        {
                const char * nameCopy = name; //casting
                delete toReturn;
                copyString(nameCopy, toReturn);
                delete nameCopy;
                return 1;
        }
        else
        {
                toReturn = NULL;
                return 0;
        }
}

これは copyString() 関数です。

int Customer::copyString(const char *& toCopy, char *& set)
{
        //prevent strlen or strcpy from being called on NULL
        if (!toCopy)
                return -1;

        //copy data into new char * and set "set"
        int length = strlen(toCopy) + 1;
        char * new_name = new char[length];
        strcpy(new_name, toCopy);

        delete set; //delete anything pointed to by this
        set = new_name;
        return 1;
}

また、質問を避けるために、cstring ライブラリを使用しています。これは、受講しているクラスの要件であるためです。この時点で自分のコードをプロファイリングすることで、それ以上のことを行っています...できるだけ多くのことを学ぼうとしています...ありがとう!

4

2 に答える 2

3

定数文字列はin にconst char * name = "bunches, oates";渡されます。deleteCustomer::getName(char* &toReturn)

于 2012-07-18T05:12:27.673 に答える
1

まず第一に、アプリケーションが長時間実行されず、多くの問題を引き起こさないことが確実でない限り、メモリ リークの修正を試みる必要があります。ただし、修正しないことを正当化するためにこれを使用しないでください。アプリケーションが大きくなると、多くの問題が発生する可能性があります。

次に、C++ と C スタイルの文字列を使用していることに気付きました。stl::string を使用することをお勧めします。これは、既にメモリを管理しているためです。一方、char* 文字列を使用すると、すべて自分で行う必要があり、間違いが非常に簡単に見える可能性があります。

于 2012-07-18T05:13:58.733 に答える