נושאים פעיליםנושאים פעילים  הצגת רשימה של חברי הפורוםרשימת משתמשים  חיפוש בפורוםחיפוש  עזרהעזרה
  הרשמההרשמה  התחברותהתחברות RSS עדכונים
תיכנות
RSS UnderWarrior Forums : RSS תיכנות
נושא

נושא: שפת C - הקצאה דינמית - בעייה עם free()

שליחת תגובהשליחת נושא חדש
כותב
הודעה << נושא קודם | נושא הבא >>
חיימון
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 11 October 2006 בשעה 20:40 | IP רשוּם
ציטוט חיימון

שלום לכולם

אני מנסה לכתוב תוכנית פשוטה של ניהול פגישות ע"י מבנים והקצאות דיכרון דינמיות

הבעייה שלי היא עם הפונקציה delete_meeting - בסוף העמוד.

התוכנית נסגרת לאחר כמה שלבים : כאשר אני מוסיף פגישות ומוחק את האחרונות שהכנסתי בזו אחר זו ובא להכניס שוב פגישה- אז היא קורסת

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

מה שלא עשיתי, לא הצלחתי לעלות על הטעות, האם יש מישהו שמצליח לראות למה?

תודה רבה לכולם

קוד:
meeting *del_meeting(meeting *detailes,int *cptr,int which

)

{

meeting *ptr=NULL;

int i;

if(*cptr==1)

{

free(detailes);

(*cptr)--;

return ptr;

}

ptr=detailes;

detailes=(meeting*)malloc( sizeof(meeting) * (*cptr-1) );

if(detailes==NULL)

{

puts("Error in memory allocation.");

exit(1);

}

for(i=0;i<which;i++)

detailes=ptr;

for(i=which;i<(*cptr);i++)

detailes=ptr[i+1];

(*cptr)--;

free(ptr);

return detailes;

}

 

הקוד יוצא פה על הפנים אז אפשר להעתיק ולהדביק לעורך טקסט בשביל שיראה נורמלי

חזרה לתחילת העמוד הצג את כרטיס החבר של חיימון חפש הודעות אחרות של חיימון בקר בדף הבית של חיימון
 
Fate
פורומיסט על
פורומיסט על
סמל אישי

הצטרף / הצטרפה: 25 October 2005
משתמש: מנותק/ת
הודעות: 571
נשלח בתאריך: 11 October 2006 בשעה 20:47 | IP רשוּם
ציטוט Fate

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

מה שהופך את זה לחסר תועלת:
קוד:

for(i=0;i<which;i++)

detailes=ptr;



חזרה לתחילת העמוד הצג את כרטיס החבר של Fate חפש הודעות אחרות של Fate
 
חיימון
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 11 October 2006 בשעה 22:00 | IP רשוּם
ציטוט חיימון

זה בסדר

כי כל for בתוכנית הזו אמור לבצע רק את ההוראה שאחריו ולא יותר מזה

לא צריך בלוק כאשר יש רק הוראה אחת.

ואתה צודק , זה אכן לא ברור כי לא מצאתי דרך להוסיף את הקובץ המקורי

וה copy-paste הרס את כל האינדטציה

חזרה לתחילת העמוד הצג את כרטיס החבר של חיימון חפש הודעות אחרות של חיימון בקר בדף הבית של חיימון
 
חיימון
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 11 October 2006 בשעה 22:30 | IP רשוּם
ציטוט חיימון

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

קוד:

meeting *del_meeting(meeting *detailes,int *cptr,int which)
{
 meeting *ptr=NULL;
 int i;
 
  if(*cptr==1)
  {
   free(detailes);
   (*cptr)--;
   return ptr;
  }

  ptr=detailes;
  detailes=(meeting*)malloc( sizeof(meeting) * (*cptr-1) );
  if(detailes==NULL)
  {
   puts("Error in memory allocation.");
   exit(1);
  }
  
  for(i=0;i<which;i++)
   detailes=ptr;
  
  for(i=which;i<(*cptr);i++)
   detailes=ptr[i+1];
  
  
  (*cptr)--;
  free(ptr);
  return detailes;
}

הסברים

cptr- מצביע למשתנה שמכיל את מס' הפגישות הקיימות

which- משתנה שמכיל בתוכו את מס' התא שרוצים למחוק

תפקיד הפונקציה:

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

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

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

הבעייה מתחילה כאשר אני משחרר את המצביע - ה debugger מתריע וסוגר את התוכנית

הנה כל הקוד  :

קוד:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct{

 char date[9];
 char description[30];
 char time[5];
 char notes[20];

}meeting;

meeting *add_meeting(meeting *detailes,int *cptr)
{
 meeting *ptrtemp;
 int i;

 ptrtemp=detailes;

 detailes=(meeting*)malloc( sizeof(meeting) * (*cptr+1) );
 if(detailes==NULL)
 {
  puts("Error...");
  exit(1);
 }
 for(i=0;i<*cptr;i++)
  detailes=ptrtemp;
 
 (*cptr)++;
 
 printf("\nEnter Meeting Date DD\\MM\\YY : ");
 flushall();
 gets(detailes.date);
 printf("\nEnter Metting description: ");
 flushall();
 gets(detailes.description);
 printf("\nWhat Time is the date ? (H:M) : ");
 flushall();
 gets(detailes.time);
 printf("\nNote: (Hit 0 for None)");
 if(detailes.notes[0]=='0')
  strcpy(detailes.notes,"None");

 else gets(detailes.notes);
          
 free(ptrtemp);
 return detailes;
}


meeting *del_meeting(meeting *detailes,int *cptr,int which)
{
 meeting *ptr=NULL;
 int i;
 
  if(*cptr==1)
  {
   free(detailes);
   (*cptr)--;
   return ptr;
  }

  ptr=detailes;
  detailes=(meeting*)malloc( sizeof(meeting) * (*cptr-1) );
  if(detailes==NULL)
  {
   puts("Error in memory allocation.");
   exit(1);
  }
  
  for(i=0;i<which;i++)
   detailes=ptr;
  
  for(i=which;i<(*cptr);i++)
   detailes=ptr[i+1];
  
  
  (*cptr)--;
  free(ptr);
  return detailes;
}


void print_meeting(meeting *meet)
{
 printf("\nDate : ");
 puts(meet->date);
 printf("\nDescription : ");
 puts(meet->description);
 printf("\nTime : ");
 puts(meet->time);
 printf("\nNotes : "); 
 puts(meet->notes);
}

int main_menu()
{
 int choose=0;
 do
 {
  printf("\nPlease Choose one of the following\n");
  printf("1. Add Meeting\n");
  printf("2. Delete Meeting\n");
  printf("3. Update Meeting\n");
  printf("4. See all of my Meetings\n");
  printf("5. Exit\n");
  scanf("%d",&choose);

  if(choose==5)
   exit(0);

 }while(choose!=1 && choose!=2 && choose!=3 && choose!=4);
 
  return choose;
}

int update_meeting_menu()
{
 int choose=0;
 do
 {
  printf("\nWhat whould you like to update in this meeting?");
  printf("\n1. date");
  printf("\n2. description");
  printf("\n3. time");
  printf("\n4. notes");
  printf("\n5. nothing - EXIT");
  scanf("%d",&choose);
  if(choose==5)
   break;
 
 }while(choose!=1 && choose!=2 && choose!=3 && choose!=4);
 
 return choose;
}

void update_meeting(meeting *meet,int who,int what)
{
 char temp[20];
 meeting *temptr;
 
 temptr=meet+who;
 switch(what)
 {
 case 1://date

  printf("\nEnter new Date : ");
  flushall();
  gets(temp);
  strcpy(temptr->date,temp);
  break;

 case 2://description

  printf("\nEnter new Description : ");
  flushall();
  gets(temp);
  strcpy(temptr->description,temp);
  break;

 case 3://time

  printf("\nEnter new Time : ");
  flushall();
  gets(temp);
  strcpy(temptr->time,temp);
  break;

 case 4://notes

  printf("\nEnter new Time : ");
  flushall();
  gets(temp);
  strcpy(temptr->notes,temp);
  break;


 }


void main()
{

 meeting *meetptr=NULL;
 int i,choose,counter=0,who,what;


  printf("=== welcome yada yada ===\n");
  
  do{
   choose=main_menu();

   switch(choose)
   {
   case 1://add 
    meetptr=add_meeting(meetptr,&cou nter);
    break;

   case 2://delete 
    if(counter>0)
    {
     for(i=0;i<counter;i++)
     {
      printf("\n=== Meeting no %d ===\n",i);
      print_meeting(&meetp tr);
     }
     printf("Choose Meeting to delete\n");
     scanf("%d",&who);
     meetptr=del_meeting(meetptr,&a mp;counter,who);
     break;
    }
    printf("\n=== Nothing to delete ===\n");
    break;

   case 3://update
    if(counter>0)
    {
     for(i=0;i<counter;i++)
     {
      printf("\n=== Meeting no %d ===",i);
      print_meeting(&meetp tr);
     }
     printf("Choose Meeting to Update:\n");
     scanf("%d",&who);
     printf("Which field whould you like to Update?\n");
     what=update_meeting_menu();
     if(what==5)
      break;

     update_meeting(meetptr,who,wha t);
     break;
    }

    printf("\n=== Nothing to Update ===\n");
    break;

     

   case 4://print all data

    if(counter>0)
    {
     for(i=0;i<counter;i++)
     {
      printf("\n=== Meeting no %d ===\n",i);
      print_meeting(&meetp tr);
     }
     break;
    }
    printf("\n=== Empty - so get back to work! ===\n");
   }
  }while(1);

}

 

 

חזרה לתחילת העמוד הצג את כרטיס החבר של חיימון חפש הודעות אחרות של חיימון בקר בדף הבית של חיימון
 
Fate
פורומיסט על
פורומיסט על
סמל אישי

הצטרף / הצטרפה: 25 October 2005
משתמש: מנותק/ת
הודעות: 571
נשלח בתאריך: 12 October 2006 בשעה 14:11 | IP רשוּם
ציטוט Fate

= לא מעתיק את התוכן...
אתה צריך להשתמש בmemcpy אם כל איבר אצלך בזיכרון הוא struct...
חזרה לתחילת העמוד הצג את כרטיס החבר של Fate חפש הודעות אחרות של Fate
 
חיימון
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 12 October 2006 בשעה 15:17 | IP רשוּם
ציטוט חיימון

תיקנתי ועכשיו זה עובד

איזה מלך

תודה!!!

חזרה לתחילת העמוד הצג את כרטיס החבר של חיימון חפש הודעות אחרות של חיימון בקר בדף הבית של חיימון
 
SlimShady
משתמש מתחיל
משתמש מתחיל
סמל אישי

הצטרף / הצטרפה: 01 October 2006
מדינה: Israel
משתמש: מנותק/ת
הודעות: 28
נשלח בתאריך: 13 October 2006 בשעה 10:17 | IP רשוּם
ציטוט SlimShady

למה לא להשתמש כבר ברשימה מקושרת וזהו?

__________________
A little C4 knocking on your door
חזרה לתחילת העמוד הצג את כרטיס החבר של SlimShady חפש הודעות אחרות של SlimShady
 

אם ברצונך להגיב לנושא זה עליך קודם להתחבר
אם אינך רשום/ה כבר עליך להרשם

  שליחת תגובהשליחת נושא חדש
גרסת הדפסה גרסת הדפסה

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