3
struct DVDInfo  *ReadStruct( void ) {
    struct DVDInfo  *infoPtr;
    int             num;
    char            line[ kMaxLineLength ];
    char            *result;

    infoPtr = malloc( sizeof( struct DVDInfo ) );

    if ( NULL == infoPtr ) {
        printf( "Out of memory!!!  Goodbye!\n" );
        exit( 0 );
    }

    printf( "Enter DVD Title:  " );
    result = fgets( line, kMaxLineLength, stdin );
    line[ strlen( line ) - 1 ] = '\0';
    infoPtr->title = MallocAndCopy( line );

    printf( "Enter DVD comment:  " );
    result = fgets( line, kMaxLineLength, stdin );
    line[ strlen( line ) - 1 ] = '\0';
    infoPtr->comment = MallocAndCopy( line );

    do {
        printf( "Enter DVD Rating (1-10):  " );
        scanf( "%d", &num );
        Flush();
    }
    while ( ( num < 1 ) || ( num > 10 ) );

    infoPtr->rating = num;

    printf( "\n----------\n" );

    return( infoPtr );
}

上記の変数「結果」を持つ目的は何ですか? それに対して何も行われていません。fgets から返されたポインタはそこに格納されますが、それだけです。目的はありません。

4

3 に答える 3

2

その結果を単に無視するのではなく、NULL についてテストして、EOF 条件またはエラーをチェックする必要があります。また、結果をチェックしないことで、 fgets が失敗したため、初期化されていないデータを持つ可能性のあるオンラインで strlen を実行しています。本当に、fgets の後に次のようにする必要があります。

if (!result)
{
  free(infoPtr); // To not leak the object allocated at the start
  return NULL; // Function failed
}

最初の fgets が成功し、2 番目が失敗した場合、構造体のポインター メンバーへの追加の割り当てがあるため、まだリークが発生している可能性があります。残念ながら、構造体は 0 に初期化されていないため、これらのポインターの NULL をチェックすることはできません。したがって、malloc の代わりに calloc を使用するか、少なくともすべての構造体ポインタ メンバを NULL に初期化する方がよいでしょう。

于 2010-10-13T18:32:05.097 に答える
2

誰かがエラー チェックの実装を開始したようですが、最終的に失敗しました。戻り値は と比較NULLされ、等しい場合はエラーが報告されます。

于 2010-10-13T18:32:57.670 に答える
0

ほとんどの場合、無視された関数の戻り値に関する警告がコンパイラによってスローされました。プログラマーは の戻り値を気にせずfgets、単純に に追加してresult =、コンパイラーがそれについてしつこく言わないようにしました。正しい解決策は、戻り値をチェックして、関数が正常に完了したことを確認することです。

于 2010-10-13T18:35:53.330 に答える