ברוס וויין פורסם 2018 בדצמבר 2 Share פורסם 2018 בדצמבר 2 בניתי תוכנית שקולטת מספרים שלמים ובונה מהם קבוצה. הפונקציה get_set קולטת נתונים ואם הם לא נמצאים בקבוצה היא מכניסה אותם. הפונקציה print_set מדפיסה את האיברים. התוכנית עברה קומפילציה ורצה כמו שצריך, אבל כשאני בודק אותה בואלגרינד היא מראה שגיאה. אבל אני לא מצליח לראות מה לא בסדר. התוכנית /*this program gets a list of integers and create a set*/ #include <stdio.h> #include <stdlib.h> #define SET_SIZE 64 /*the set size*/ /*functions prototypes*/ void get_set(int *s, int *len); void print_set(int *s,int len); int check(int *s,int x, int len); /* data structure: dinamic array, the size of the set unknown. the range between 0-64. so dinamic array selected to avoid waste of memory */ int main(){ int *set = (int *) calloc(1 ,sizeof(int)); /*array for the set*/ int len = 0; /*array length*/ if(set==NULL){ /*if the allocation is faild*/ printf("the segmentayion is failed"); exit(0); } printf("enter numbers \n"); get_set(set,&len); print_set(set,len); printf("\n"); free(set); /*return the memory block to the OP*/ return 0; } /*the function get_set gets an array and making a set of values*/ /* get_set args: (*set) array of ints (int*) pointer of int (array length) return: void */ void get_set(int *set, int *len){ int x; /*scan a numbers until get EOF*/ while(scanf("%d",&x)!=EOF){ printf("you have entered %d \n",x); /*print the input*/ int *p=set; /*check if x is not in the set and the set isnt full*/ if(check(set,x,*len)==0 && *(len) < SET_SIZE){ *(set+*len)=x;/*put x in the set*/ (*(len))++; p= (int *)realloc(set,(*len +1)*sizeof(int)); if(p==NULL){ printf("ALLOCATION FAIND"); exit(0); } set=p; } } } /*print_set print the set*/ /* print_set args: (int *) array (int) the array length return: void */ void print_set(int *set,int len){ int i; for(i=0;i<len;i++){ printf("%d ",set); } } /*this is auxilary function for checking if x is in the set */ /* args: (set*) array (int) the input (int) array length return: (int), 1 if x is in the array otherwise return 0 */ int check(int *set,int x, int len){ int i; for(i=0;i<len;i++){ if(set==x){ return 1; } } return 0; } השגיאה ==1771== Invalid read of size 4 ==1771== at 0x80486D4: print_set (my_set.c:92) ==1771== by 0x80485D0: main (my_set.c:30) ==1771== Address 0x41f2030 is 4 bytes after a block of size 4 free'd ==1771== at 0x402BF52: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-Linux.so) ==1771== by 0x8048674: get_set (my_set.c:65) ==1771== by 0x80485BC: main (my_set.c:29) ==1771== 0 0 ==1771== Invalid free() / delete / delete[] / realloc() ==1771== at 0x402B06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-Linux.so) ==1771== by 0x80485E8: main (my_set.c:32) ==1771== Address 0x41f2028 is 0 bytes inside a block of size 4 free'd ==1771== at 0x402BF52: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-Linux.so) ==1771== by 0x8048674: get_set (my_set.c:65) ==1771== by 0x80485BC: main (my_set.c:29) ==1771== ==1771== ==1771== HEAP SUMMARY: ==1771== in use at exit: 12 bytes in 1 blocks ==1771== total heap usage: 3 allocs, 3 frees, 24 bytes allocated ==1771== ==1771== LEAK SUMMARY: ==1771== definitely lost: 12 bytes in 1 blocks ==1771== indirectly lost: 0 bytes in 0 blocks ==1771== possibly lost: 0 bytes in 0 blocks ==1771== still reachable: 0 bytes in 0 blocks ==1771== suppressed: 0 bytes in 0 blocks ==1771== Rerun with --leak-check=full to see details of leaked memory ==1771== ==1771== For counts of detected and suppressed errors, rerun with: -v ==1771== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0) קישור לתוכן שתף באתרים אחרים More sharing options...
Jabberwock פורסם 2018 בדצמבר 2 Share פורסם 2018 בדצמבר 2 realloc - לא בהכרח מחזיר את אותו המצביע שמכניסים אליו. כלומר ייתכן מצב שהוא בעצם עושה malloc, מעתיק את התוכן של המצביע הקודם ואז עושה free. קישור לתוכן שתף באתרים אחרים More sharing options...
ברוס וויין פורסם 2018 בדצמבר 2 מחבר Share פורסם 2018 בדצמבר 2 ציטוט של Jabberwock realloc - לא בהכרח מחזיר את אותו המצביע שמכניסים אליו. כלומר ייתכן מצב שהוא בעצם עושה malloc, מעתיק את התוכן של המצביע הקודם ואז עושה free. אני יודע. בגלל זה בדקתי אם ההקצאה הצליחה. אם לא אני מעיף את התוכנית. אם הצליח set מקבל את מה שrealloc מחזירה. קישור לתוכן שתף באתרים אחרים More sharing options...
Jabberwock פורסם 2018 בדצמבר 2 Share פורסם 2018 בדצמבר 2 ציטוט של ברוס וויין אם הצליח set מקבל את מה שrealloc מחזירה המשתנה set מקבל אליו את הערך של p רק בפונקציה. מחוצה לה המשתנה set נשאר עם הערך הקדמון. קישור לתוכן שתף באתרים אחרים More sharing options...
ברוס וויין פורסם 2018 בדצמבר 2 מחבר Share פורסם 2018 בדצמבר 2 ציטוט של Jabberwock המשתנה set מקבל אליו את הערך של p רק בפונקציה. מחוצה לה המשתנה set נשאר עם הערך הקדמון. אבל set הוא מצביע. הוא לא אמור להיות עם ערך אחר מחוץ לפונקציה. וגם אם השגיאה בגלל זה התכנית לא הייתה עובדת לי. אבל היא רצה בלי בעיות ועושה את מה שהיא אמורה לעשות. הבעיה היחידה שהואלגרינד מראה על שגיאה. קישור לתוכן שתף באתרים אחרים More sharing options...
Jabberwock פורסם 2018 בדצמבר 3 Share פורסם 2018 בדצמבר 3 הוא מצביע למערך של int. כלומר הערך שלו היא כתובת בזיכרון למערך הנ"ל. זה שאתה עושה עליו פעולת השמה לא אומר שהערך שלו ישתנה גם מחוץ לפונקציה. בפנים הפונקציה, set הוא משתנה זמני השמור במחסנית (stack). השגיאה שאתה רואה היא אזהרה על זליגת זיכרון. פיתרון אפשרי הוא להכניס אותו כרפרנס לפונקציה. כלומר מצביע למצביע. בכל שלב תנסה לדבג את הקוד שלך, גם על הכתובות עצמן ותנסה להבין מה קורה. קישור לתוכן שתף באתרים אחרים More sharing options...
ברוס וויין פורסם 2018 בדצמבר 3 מחבר Share פורסם 2018 בדצמבר 3 ציטוט של Jabberwock הוא מצביע למערך של int. כלומר הערך שלו היא כתובת בזיכרון למערך הנ"ל. זה שאתה עושה עליו פעולת השמה לא אומר שהערך שלו ישתנה גם מחוץ לפונקציה. בפנים הפונקציה, set הוא משתנה זמני השמור במחסנית (stack). השגיאה שאתה רואה היא אזהרה על זליגת זיכרון. פיתרון אפשרי הוא להכניס אותו כרפרנס לפונקציה. כלומר מצביע למצביע. בכל שלב תנסה לדבג את הקוד שלך, גם על הכתובות עצמן ותנסה להבין מה קורה. כן אתה צודק. זה הבעיה. הייתי צריך לשלוח רפרנס. בסוף שיניתי קצת את הפונקציה והחזרתי ממנה את set. אבל אם זאת הבעיה למה התוכנית עבדה לי כמו שצריך? זה לא הזהיר אותי בקומפיילר וכשהרצתי אותה היא עשתה את העבודה שלה. רק כשהרצתי אותה בואלגרינד ראיתי שיש שגיאה. עריכה: יכול להיות שבגלל שהגדרתי במיין את set והקצאתי לה זיכרון זה עבד? כלומר בגלל שset שהוגדר בmain הפנה לכתובת בזיכרון, והrealloc רק הגדיל את אותו רצף? אז בעצם עברתי לתא הבא בזיכרון. אבל אם נגיד הrealloc היה מעביר אותי למקום אחר אז זה לא היה עובד כמו שצריך? קישור לתוכן שתף באתרים אחרים More sharing options...
Jabberwock פורסם 2018 בדצמבר 3 Share פורסם 2018 בדצמבר 3 הסוד טמון בואלגרינד. ד"א לפי המיתלוגיה הנורדית הוא שמו של השער לולהאלה, היכלו של האל אודין. קישור לתוכן שתף באתרים אחרים More sharing options...
Recommended Posts
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.