سؤال
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 فيه ، ولكن هذا هو ، ليس له أي غرض.
المحلول
يجب عليك اختبار هذه النتيجة لـ NULL ، للتحقق من حالة EOF أو خطأ ، بدلاً من مجرد تجاهلها. أيضًا ، من خلال عدم التحقق من النتيجة ، تقوم بعمل Strlen عبر الإنترنت ، والتي يمكن أن تحتوي على بيانات غير مضادة ، لأن FGTS فشلت. حقا ، يجب أن يكون لديك ، بعد fgets:
if (!result)
{
free(infoPtr); // To not leak the object allocated at the start
return NULL; // Function failed
}
ربما لا يزال لديك تسرب ، إذا نجحت FEGTs الأولى وفشل الثاني ، لأن هناك تخصيصًا إضافيًا لأعضاء المؤشر في الهيكل. لسوء الحظ ، نظرًا لعدم تهيئة البنية إلى الصفر ، لا يمكنك التحقق من هذه المؤشرات لـ NULL. لذلك ، ربما كان استخدام Calloc بدلاً من Malloc أو على الأقل تهيئة جميع أعضاء مؤشر البنية إلى Null ، سيكون فكرة أفضل.
نصائح أخرى
يبدو كما لو كان شخص ما بدأت لتنفيذ التحقق من الأخطاء ، ولكن فاشله في النهاية. يجب مقارنة قيمة الإرجاع مع NULL
, ، مع خطأ تم الإبلاغ عنه إذا كان متساوٍ.
على الأرجح ، ألقى المترجم تحذيرًا حول قيمة إرجاع الوظيفة التي تم تجاهلها. لم يهتم المبرمج بقيمة إرجاع fgets
وأضاف ببساطة في result =
لجعل المترجم يتوقف عن التذمر حول هذا الموضوع. سيكون الحل الصحيح هو التحقق من قيمة الإرجاع للتأكد من اكتمال الوظيفة بنجاح.