הקצאה דינמית C למחרוזת - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

הקצאה דינמית C למחרוזת


davidfa89

Recommended Posts

הייי

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

התוכנית קורסת מיידית אחרי הכניסה לתנאי if (test == 0 ) משום בהקצאה הדינמית של CHAR קורס אצלי

כל התוכנית בלינק :

http://pastebin.com/raw.php?i=14Qf2a0E

אשמח לעזרה תודה :)

קישור לתוכן
שתף באתרים אחרים

בעיקרון השורה הזו כן עושה את מה שאמרת אבל היא נועדה בשביל הMALLOC שיתבצע בפונקציה אחרת בכלל

אחת מ2 השורות הללו גורמת לבעיה :

ptr->arrplayers[ptr->numofplayers].fname = (char*) malloc (sizeof (char)*(strlen(temp1)+1));

strcpy( ptr->arrplayers[ptr->numofplayers].fname , temp1);

יש לי מספר זוגות כאלה בפונקציה הזו ובפרט בפונקציות האחרות

קישור לתוכן
שתף באתרים אחרים

כשאתה כותב קוד בפורום, שים אותו בתוך טג קוד.

בעיקרון השורה הזו כן עושה את מה שאמרת אבל היא נועדה בשביל הMALLOC שיתבצע בפונקציה אחרת בכלל

מה זאת אומרת? לא הבנתי. אתה לא יכול להקצות משהו בגודל 0 ואחר כך להשתמש בו... במקרה הטוב זה יעיף לך שגיאה, במקרה הרע זה יעשה לך דריסות .

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

חוץ מזה, הערת אגב: אין צורך לכפול ב-(sizeof(char, כי הוא תמיד 1 (זה חלק מהתקן של C).

וסתם עוד הערה אסתטית: תן לסוגריים המסולסלים את הכבוד שלהם, ושים סוגריים מסולסלים סוגרים בשורה משלהם (כמו שעשית בסוף ה-for ובסוף של הפונקציות). ככה ברור יותר מתי נגמר הבלוק.

קישור לתוכן
שתף באתרים אחרים

כן ע"פ ההוראות של התרגיל קלט לא יגדל מעל ל15 תווים אז מהבחינה הזו אין בעיה.

בDEBUG שאני עושה אני לא מצליח לאתר את השגיאה ,


ptr->arrplayers[ptr->numofplayers].fname = (char*) malloc (sizeof (char)*(strlen(temp1)+1));
strcpy( ptr->arrplayers[ptr->numofplayers].fname , temp1);

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

למרות שבכתיבה של הקוד בVB הוא לא מציג לי שום שגיאת SYNTEX .

קישור לתוכן
שתף באתרים אחרים

אני מניח שאתה מתכוון ל-VS ולא VB.

VS = Visual Studio, VB = Visual Basic.

שגיאת syntax הייתה גורמת לזה שהקוד בכלל לא היה מתקמפל ורץ, לא שהוא היה רץ וקורס.

הכפל ב-sizeof זה היה סתם הערה טכנית, זה לא אמור לשנות כלום.

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

שים לב שיש לך שיש באג קטן גם בלולאה שבה אתה מחפש אם יש כבר שחקן עם ה-ID שנקלט.

איזה מין debug ניסית לעשות? עברת על הקוד step by step? בדקת את הערכים של כל המשתנים בכל שלב?

קישור לתוכן
שתף באתרים אחרים

כיצד אתה מייעץ לשנות את השורה הזו ?


L1.teamarr = (team*) malloc ( 0 * sizeof(L1.teamarr));

בעיקרון אני פשוט רוצה להקצות 0 מקום כבר בMAIN כדי שאוכל לבצע REALLOC בפונקציה עצמה

ללא תנאי IF כזה או אחר שיבדוק את הגודל

אלא לבצע מראש הקצאה ל0 ובפונקציה עצמה REALLOC כבר כל פעם להגדיל ב1

תשים לב בבקשה שב2 שורות בהן מתבצעת השמה של CHAR

אין קשר לL1.teamarr

אלא השמה לתוך מערך נפרד לחלוטין שלא אותחל בשום אופן לפני

קישור לתוכן
שתף באתרים אחרים

כן ע"פ ההוראות של התרגיל קלט לא יגדל מעל ל15 תווים אז מהבחינה הזו אין בעיה.

בDEBUG שאני עושה אני לא מצליח לאתר את השגיאה ,


ptr->arrplayers[ptr->numofplayers].fname = (char*) malloc (sizeof (char)*(strlen(temp1)+1));
strcpy( ptr->arrplayers[ptr->numofplayers].fname , temp1);

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

כתוב פונקציה שעושה שיכפול כזה, ואת הפוינטר המתקבל ממנה שמור במבנה שלך וזהו.

חפש ברשת על strdup זוהי פונקציה לא סטנדרטית אבל קיימת ברבות מספריות ה-C וממילא קל מאד לממש אותה.

קישור לתוכן
שתף באתרים אחרים

סידור מחדש שלהן בפונקציה משלהן עשה את העבודה :)

מה זאת אומרת סידור מחדש שלהן? מה עשית בדיוק?

בכל מקרה, הבעיה היא לא הקצאה בגודל 0 - הבעיה היא ששורה אחרי זה אתה מנסה להשתמש בזכרון שהוקצה!

קישור לתוכן
שתף באתרים אחרים

שוב תודה על העזרה

אך עדיין יש לי בעיה קטנה בתוכנית

הפונקציה void freememory משחררת את כל הזיכרון הדינמי שהוקצה במהלך התוכנית

היא עובדת תקין למעט השורה למטה שמסומנת באדום

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

קישור לתוכן
שתף באתרים אחרים

זה כל הקוד של התכנית שלך?

אז ברור שיש בעיה - אתה מנסה לשחרר שמעולם לא הקצית.

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

קישור לתוכן
שתף באתרים אחרים

יש בתוכנית עצמה סה"כ כ10 פונקציות

זו אחת מהן

האחרונה שמשחררת את הזיכרון הדינמי שהוקצה

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

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...