3

過去数か月間動作していた次のコードがありますが、最近、ときどきクラッシュし始めました (マルチスレッド アプリケーションで実行している場合)。

struct some_struct {
    char* m_str1;
    char* m_str2;
}

struct some_struct*
set_some_struct(const char* p_str1, const char* p_str2) {
    struct some_struct* some_struct_ptr = 
        (struct some_struct*)malloc(sizeof(struct some_struct));
    if (some_struct_ptr == NULL)
        printf("malloc failed!\n");

    size_t str1_len = strlen(p_str1) + 1;
    size_t str2_len = strlen(p_str2) + 1;

    some_struct_ptr->m_str1 = malloc(str1_len);
    if (some_struct_ptr->m_str1 == NULL)
        printf("malloc failed!\n");

    some_struct_ptr->m_str2 = malloc(str2_len); // Crashes here
    if (some_struct_ptr->m_str2 == NULL)
        printf("malloc failed!\n");

    strcpy(some_struct_ptr->m_str1, p_str1);
    strcpy(some_struct_ptr->m_str2, p_str2);

    return some_struct_ptr;
}

実行すると、「「0x7c81bb52」の命令が「0x00000002」のメモリを参照しました。メモリを「読み取る」ことができませんでした。

上記のコードに、特定の状況下で誤動作する可能性のある明らかな問題はありますか? テスト プログラムで関数を単独で実行すると問題なく動作しますが、完全なアプリケーションで実行すると常にクラッシュします。3 番目の malloc に至るまではすべて問題ないようです。

編集:mallocさらなる調査により、これが台無しになったのは以前の呼び出しであると私は信じるようになりました。そのようなことは可能ですか?以前に行われた関数呼び出しのコメントを外し、それset_some_structがいくつか含まれていると、問題なく実行されます。mallocsset_some_struct

4

2 に答える 2

2

割り当てが失敗したときに行うことは、エラーを出力することだけです。おそらく印刷が落ちているか、それを見逃していますか?これを実行しているスレッドが複数ある場合、出力が混乱する可能性があります。

次に、入力ポインターをチェックしていません。クラッシュは読み取りであり、ポインターを介した他のすべてのアクセスは新しく割り当てられた領域への書き込みであるため、1 つ以上の引数がNULLポインターであると思われます。それを確認する必要があります。

malloc()また、 Cでの戻り値をキャストするべきではありません(理由については、こちらを参照してください)。これを含めない場合、stdlib.hエラーが隠れている可能性があります。

文字列が定数の場合、 を 1 回呼び出すだけでメモリと速度を節約できますmalloc()。もちろん、最初に 3 つの割り当てのサイズを合計してから、それに応じてポインタを設定します。

于 2013-01-17T10:42:26.270 に答える
1
if (some_struct_ptr == NULL)
    printf("malloc failed!\n");

この時点から、ガベージ ポインターを使用しています。次のコードでも同じ問題が発生します。

if (some_struct_ptr->m_str1 == NULL)
    printf("malloc failed!\n");

if (some_struct_ptr->m_str2 == NULL)
    printf("malloc failed!\n");
于 2013-01-17T12:05:13.000 に答える