פורסם 2012 ביולי 413 שנים התכנית עובדת, אבל בסוף ההרצה מופיעה הודעת השגיאה:stack around the variable 'st1' was corruptedהבעיה היא בשתי הפונקציות.מה הבעיה?#include <string.h>#include <stdlib.h>#include<stdio.h>void rle (char *s1, char*s2){ int count=1, i, j = 0; for (i = 0; s1[i] != '\0';i++){ count = 1; while(s1[i] == s1[i+1]){ count++; i++; } s2[j++] = count+'0'; s2[j++] = s1[i]; } s2[j] = '\0';}char *rleReverse(char *str){ int i=0, j=0, count=0; char *ans ; for (i = 0; i<strlen(str);i++) if (str[i] >= '0' && str[i]<= '9') count = count+ (str[i]-'0'); ans = (char*)malloc(count*sizeof(char)); for(i = 0;str[i] != '\0'; i = i+2){ count = j+ str[i] - '0'; for(; j<count; j++) ans[j] = str[i+1]; } ans[j] = '\0'; return ans;}void main(){ char st1[] = "aaaaddrrqqqqqsss", st2[] = "bcd"; rle(st1, st2); printf("rle: %s\n", st2); printf("rerle: %s\n", rleReverse(st2));}
פורסם 2012 ביולי 413 שנים כמה בעיות נראות לעין:* הלולאה החיצונית בrle אמנם בודקת שלא גלשת מתחום המחרוזת, אך הלולאה הפנימית לא בודקת. ברגע שעשית i++ פעם אחת - יכול להיות שs1[i+1] 1 מצביעה לזכרון לא מאותחל.* באותה פונקציה - אתה לא מקצה מקום לs2, רק כותב לשם. אתה מניח שזה גדול מספיק? בדוגמה אתה מעביר st2 באורך 3 וכותב לשם 10 פעמים.
פורסם 2012 ביולי 413 שנים מחבר זה לא הרעיון במצביעים, שאפשר לחרוג מגבולות המערך / לא להקצות גודל סופי?הרי זה רק מראה באיזה מקום בזיכרון נמצאים.
פורסם 2012 ביולי 413 שנים מחבר ממש נחמד... למה אסור? מה זה עושה? ואם זה אסור, איך זה שהתכנית פועלת? אמנם עם הערת שגיאה, אבל בכל זאת... אז איך אפשר ליצור מערכים בלי לדעת את גודלם מראש, אפילו לא כמשתנה? תמיד צריך לקבוע גודל מקסימלי מרבי? חבל על המקום...
פורסם 2012 ביולי 413 שנים אסור - כי אתה יכול לדרוס זיכרון שלא שייך לך. אתה יכול לדרוס זכרון שבו יושב משתנה אחר שלך, או זכרון של תכנית אחרת או אפילו של מערכת ההפעלה. התוצאות פשוט בלתי-צפויות. איך זה פועל - כי במקרה לא דרסת שום דבר חשוב. איך אפשר ליצור מערכים בלי לדעת גודל מראש? * אם אתה יודע את הגודל בשלב כלשהו אתה יכול לעשות malloc. * אם אתה לא יודע שום דבר - אתה יכול לעשות רשימה מקושרת שגדלה דינמית, או להקצות מערך בגודל כלשהו וכל פעם שאתה מגיע לקצה הקיבולת, להקצות אחד חדש יותר גדול ולהעתיק אליו את הישן. זה בדיוק מה שכל הספריות ושפות התכנות שמאפשרות מערכים דינמיים עושות - אין פה קסמים.
פורסם 2012 ביולי 413 שנים אסור - כי אתה יכול לדרוס זיכרון שלא שייך לך. אתה יכול לדרוס זכרון שבו יושב משתנה אחר שלך, או זכרון של תכנית אחרת או אפילו של מערכת ההפעלה. התוצאות פשוט בלתי-צפויות.איך זה פועל - כי במקרה לא דרסת שום דבר חשוב.רק חשוב לי להדגיש שזה לא נכון, מערכות הפעלה ממשות זיכרון וירטואלי פר פרוסס בימינו, מה שאומר שלא תוכל לדרוס קוד של מערכת ההפעלה. (אחרת כל עקרון הגיוני של אבטחת מידע היה הולך לפח- דרוס פונקציית קרנל ותריץ את הפונקציה שלך)
פורסם 2012 ביולי 513 שנים אתה צודק, כמובן. אנחנו כבר מזמן לא עובדים בreal mode. אבל הרבה יותר מפחיד אנשים לשמוע את זה שהם יכולים לדרוס קוד של מערכת ההפעלה.
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.