עבור לתוכן

בעיות כתיבה/קריאה מקבצים ב-C

Featured Replies

פורסם

כל עוד עשית fclose (ואלי גם אם לא) אז לא צריכה להיות בעיה. fclose מבצע fflush בעצמו.

  • תגובות 44
  • צפיות 5.3k
  • נוצר
  • תגובה אחרונה
פורסם
  • מחבר

כן עשיתי. אם כך לא יודע מה הייתה הבעיה.

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

נגיד הקציתי מקום בזכרון ל-firstptr ואז הגדרתי עוד מצביע secptr ועשיתי secptr=firstptr .

אז כאשר אני עושה

free(secptr) a

זה אמור למחוק לגמרי את המבנה נכון? שאני לא אוכל לגשת אליו גם אם firstptr , נכון?

פורסם

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

למעשה, טעות הרסנית נפוצה היא לשחרר את אותו זכרון פעמיים.

וכמובן אסור לך יותר להשתמש בזכרון ששחררת - לא לקריאה ולא לכתיבה.

פורסם

טוב תודה.

אבל עדיין לא הבנתי בדיוק איך אני משתמש בדיבאגר. מה הכוונה מקבל ערכים שלא היו אמורים להתקבל ואיך אני בודק את זה? את הסביבת שאני משתמש בה אמרתי כבר.

וחשבתי עכשיו- יכול להיות שהבעיה בקריאה/כתיבה של כל המבנה לקובץ, כמו שניסיתי בהתחלה, הייתה כי לא השתמשתי כלל בפונקציה fflush ? פתאום נזכרתי בפונקציה הזאת שקשורה לקבצים, וחשבתי אולי זה בגללה

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

לדוגמא- יצרת פונ שמעתיקה מחרוזת, ומקצה לא מקום מחדש(אולי בסדר ההפוך?). כשאתה מריץ את הפוכנית וקורא לפונ, ולאחר מכן מנסה להדפיס את המחרוזת החדשה, אתה מקבל את המחרוזת הישנה + עוד כל מיני סימנים לא מובנים. לכן, אתה עובר שורה שורה בקוד, ומגלה שהעתקת את המחרוזת בידיוק כפי שהיית צריך, רק ששכחת לשים בסוף '\0'.

ברוב המקרים השימוש בDEBUG עוזר מאוד לגלות טעויות ושגיאות שאתה מקבל בזמן הרצה.

פורסם
  • מחבר

בסדר אבל איך בדיוק משתמשים? נו נגיד אני בשורה הראשונה, אז אני משנה את I מ-0 ל-1 . מה זה נותן לי, איך זה עוזר לי לגלות את הבעיה?

פורסם

זה עוזר כשאתה עושה דברים קצת יותר מסובכים מהוספת 1 למשתנה. למה שלא תנסה להפעיל את זה?

יש לך בעיה, אני אומר לך איך לפתור אותה, ואתה שואל אותי איך הפתרון הזה עוזר לך?

פורסם
  • מחבר

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

ולא רק זה- הרי ה-DEBUGGER הזה זה איזו תוכנה בתוך הסביבת עבודה לא? אז מה אני עושה אם זה, על מה ללחוץ?

פורסם

דיבאגר זה תוכנה. יש דיבאגרים מובנים בתוך סביבת העבודה (בכל IDE נורמלי היום, כגון Visual Studio, יש דיבאגר מובנה), ויש דיבאגרים חיצוניים שמתלבשים לך על ה-source-ים וה-executables.

קח את הדוגמה הזו:

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


int func(int n) {
int sum = 0;
for (int i = 1 ; i < n ; ++i) {
sum += i;
}

return sum;
}

שים לב שיש לי באג בפונקציה - הפונקציה לא תסכום את n, כי עשיתי i < n במקום i <= n.

איך אני אשתמש בדיבאגר כדי למצוא את הבעיה?

נניח שהרצתי את הפונקציה עם n=3. אני יודע הרי שהתוצאה צריכה להיות 6, אבל היא יוצאת 3. אז באמצעות הדיבאגר אני יכול לעקוב אחרי הריצה של התכנית שורה שורה. אני אראה שבהתחלה הערך של sum הוא 0, ואז אני נכנס ללולאה, sum עולה ל-1, ואז עוד איטרציה של הלולאה, sum עולה ל-3, ואז - אין עוד איטרציה. ואז אני מבין שיש לי בעיה, כי פספסתי את האיטרציה השלישית של הלולאה. אז אני מבין שיש לי בעיה בתנאי של הלולאה - אז אני מסתכל ורואה שהייתי צריך לעשות i <= n במקום i < n.

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

פורסם

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

פורסם
  • מחבר

דיבאגר זה תוכנה. יש דיבאגרים מובנים בתוך סביבת העבודה (בכל IDE נורמלי היום, כגון Visual Studio, יש דיבאגר מובנה), ויש דיבאגרים חיצוניים שמתלבשים לך על ה-source-ים וה-executables.

קח את הדוגמה הזו:

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


int func(int n) {
int sum = 0;
for (int i = 1 ; i < n ; ++i) {
sum += i;
}

return sum;
}

שים לב שיש לי באג בפונקציה - הפונקציה לא תסכום את n, כי עשיתי i < n במקום i <= n.

איך אני אשתמש בדיבאגר כדי למצוא את הבעיה?

נניח שהרצתי את הפונקציה עם n=3. אני יודע הרי שהתוצאה צריכה להיות 6, אבל היא יוצאת 3. אז באמצעות הדיבאגר אני יכול לעקוב אחרי הריצה של התכנית שורה שורה. אני אראה שבהתחלה הערך של sum הוא 0, ואז אני נכנס ללולאה, sum עולה ל-1, ואז עוד איטרציה של הלולאה, sum עולה ל-3, ואז - אין עוד איטרציה. ואז אני מבין שיש לי בעיה, כי פספסתי את האיטרציה השלישית של הלולאה. אז אני מבין שיש לי בעיה בתנאי של הלולאה - אז אני מסתכל ורואה שהייתי צריך לעשות i <= n במקום i < n.

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

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

והבנתי את הדוגמא שנתת, אבל- בכלל לא הסברת איך אני משתמש בדיבאגר כדי לעבור שורה שורה....

יש לי תפריט DEBUG, ויש שם INSPECT או CHECK EXPRESSION, ואני נכנס לזה, אבל כל משתנה שאני רושם שם- הוא רושם לי undefined symbol x

....

פורסם

זה כבר תלוי באיזה דיבאגר יש לך.... אני לא ממש מכיר את ה-ide שאתה משתמש בו.

פורסם
  • מחבר

טוב.

UnsignedInteger שלחתי לך בפרטי הודעה .

ועכשיו אני שם לב לבעיה- הפונקציה FREE לא עובדת אצלי.

אני למשל כותב קוד כזה:

char *copy;

copy=(char*)calloc(10,sizeof(char));

strcpy(copy,"Copy");
puts(copy);
free(copy);
getch();
puts(copy);

והפלט הוא:

Copy

Copy

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

מה אני עושה?

פורסם

שיחרור לא אומר שהמידע נמחק, רק שאותו קטע בזכרון פנוי להקצאות שונות(לא בהכרח מהתוכנה שלך)

פורסם

בטורבו C אתה צריך להשתמש בתפריט RUN. תפריט הDEBUG משמש שם לצפייה בערכים של משתנים.

פורסם
  • מחבר

שיחרור לא אומר שהמידע נמחק, רק שאותו קטע בזכרון פנוי להקצאות שונות(לא בהכרח מהתוכנה שלך)

אז איך הוא פנוי לתוכניות אחרות אם התוכנית שלי עוד משתמשת בו?

ולמה ZELIG אמר פה שאסור להשתמש בזכרון ששוחרר? אם אני משתמש בו והכל עובד בסדר גמור...

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

בטורבו C אתה צריך להשתמש בתפריט RUN. תפריט הDEBUG משמש שם לצפייה בערכים של משתנים.

אה תודה, סוף סוף הבנתי מה זה....

אבל לא נראה כזה יעיל, עדיף כבר את ההדפסות עזר שלי, יותר עוזרות...

ארכיון

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

דיונים חדשים