עבור לתוכן

בעיה קשה ב-C בקריאה מקובץ בינארי באמצעות fread

Featured Replies

פורסם

שלום לכולם, יש לי בעיה שקשה לפתרון.

אני עובד בסביבת visual studio 2005, פרויקט console , בשפת C.

אני מנסה לקרוא קובץ בינארי בצורה הבאה:

(Cnt = (fread(tmp_ptr,1,sizeof(STRCT),file_ptr

כאשר STRCT הוא מבנה בגודדל 836.

בתוך המבנה STRCT יש לי עוד מבנה בשם STR1

ערך ה-Cnt שמתקבל הוא באמת בגודל 836.

אני מריץ את הקוד הזה בשתי אפליקציות שונות, אותו קטע קוד ממש, ואותו קובץ בינארי!

באפליקציה אחת, כאשר אני בודק את ה-data ב- tmp_ptr אני רואה שכל המבנה מכיל ערכים והמבנה הפנימי STR1 - אותחל באפסים - שזה טוב,

בעוד שבאפליקציה אחרת, ה- tmp_ptr דומה ב-data עד לנקודה של המבנה STR1, שם הdata שונה וחלקה לא מאותחלת אפילו.

חקרתי ובדקתי, כל הגדלים של כל המבנים זהים בגודלם, מספר הבתים שנקראים בכל אפליקציה זהה בדיוק. ההבדל הוא שבאפליקציה אחת המבנה אותחל, ובאפליקציה השנייה המבנה לא אותחל.

יש למישהו רעיון למה זה קורה? האם זה בעית קונפיגורציה כלשהי?

פורסם

נתחיל מזה שיש לך טעות קטנה ב-fread. הפרמטר השני הוא גודל המבנה, והשלישי הוא מספר העצמים לקריאה, ולא להיפך. כלומר, צריך:

fread(tmp_ptr,sizeof(STRCT),1,file_ptr)

ולא כמו שעשית. אני לא יודע אם זה משנה משהו מעשית, אבל זו הצורה הנכונה.

תוודא שאין לך איפשהו איזה buffer overflow שבטעות גורם לדריכה על המבנה או משהו כזה. תנסה לאפס את המבנה לפני ה-fread ואז לקרוא לתוכו, כדי לראות אם ה-STR1 נשאר מאופס, או שהוא מתמלא בזבל.

פורסם
  • מחבר

תודה על התגובה,

אני בכוונה עשיתי ככה על מנת שאני אוכל לראות כמה בתים הוא קורא, ולא כמה עצמים. ולכן זה איזה שהוא תיחמון שלי.

לאחר עוד מחקר קטן, הבנתי עוד משהו, המבנה הפנימי STR1 הוא לא מבנה הוא פוינטר למבנה.

לכן השאלה הופכת לשאלה הבאה:

למה באפליקציה אחת הוא אתחל לי את הפוינטר באפסים,

ובשנייה הוא לא אתחל את הפוינטר בכלל?

שוב תודה.

פורסם

קודם כל, ברגע שזה מצביע אתה לא יכול להשתמש ב-fread/fwrite, מהסיבה הפשוטה שהמצביע מאבד את המשמעות שלו.

חוץ מזה, התוכנה לא מאתחלת שום דבר שאתה לא אומר לה מפורשות לאתחל. אם לא שמת במשתנה כלשהו ערך, אז הוא פשוט יכיל זבל - מה שהיה בזכרון שבו הוא יושב כשהוא נוצר. יכול להיות שבאחת מהאפליקציות שלך הזבל הזה היה אפסים, ובשנייה היה שם תוכן ממש.

בגלל זה, כשיוצרים מבנה, חשוב תמיד לאתחל אותו לפני שעושים איתו משהו.

פורסם
  • מחבר

תודה רבה.

ההסבר באמת מתקבל על הדעת.

אתחלתי את הפוינטר ובאמת פתר את הבעיה.

תודה.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים