עבור לתוכן

לשרשר - אפשרי? C

Featured Replies

פורסם

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

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

איזה קוד אתה מתכוון שרץ לך? (תעלה אותו כאן)

פורסם
  • מחבר

בא לך לקרוא 1100 שורות קוד?

אני יעלה את המרכזי

eat(board,&xIndex,&yIndex,&x,&y,strshr((turn=='w' ? 'w' : 'b'),".k"),"rd",&bWin,&wWin);

int eat(Soldier board[][10],int* xIndex,int* yIndex,int* x,int* y,char* turn,char* direction,int* bWin,int* wWin)
{
makeAmove(board,xIndex,yIndex,x,y,turn,direction);
printf(" ");
makeAmove(board,xIndex,yIndex,x,y,turn,direction);
turn[0]=='w' ? --(*bWin) : --(*wWin);
}

char* strshr(char c, char* str)
{
char* string;
int i;

string[0]=c;

for(i=1;i<=strlen(str);++i)
string[i]=str[i-1];
string[i+1]='\0';
return(string);
}

int makeAmove(Soldier board[][10], int* xI, int* yI, int* x , int* y, char* turn, char* move)
{
strcpy(board[*yI][*xI].kind,"empty");
gotoxy(*x-1,*y);
printf(" ");
if(move[0]=='l')
{
--(*xI);
*x-=4;
}
else
{
++(*xI);
*x+=4;
}

if(move[1]=='u')
{
--(*yI);
*y-=2;
}
else
{
++(*yI);
*y+=2;
}

gotoxy(*x,*y);

if(turn[2]=='k' || (*yI==1 && turn[0]=='b') || (*yI==8 && turn[0]=='w'))
{
printf(".K");
gotoxy(*x-1,*y);
strcpy(&(board[*yI][*xI].kind[1]),".k");
}

if(turn[0]=='w')
{
printf("W");
board[*yI][*xI].kind[0]='w';
}
else
{
printf("B");
board[*yI][*xI].kind[0]='b';
}

gotoxy((*x)-1,*y);

return(1);
}

פורסם

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

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

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

פורסם
  • מחבר

אז תמיד הדרך היחידה להחזיר מחרוזת היא

א. שהפונקציה תקצה את המערך.

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

לא משנה כלום

?

פורסם
  • מחבר

הדרך היחידה להחזיר מחרוזת היא ע"י הקאצת מקום?

פורסם

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

המחרוזת הזו יכולה להיות מוקצית סטטית או דינמית.

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

לדוגמה, אתה יכול לעשות ככה:

void strshr(char c, char* str, char* dst)
{
int i;

dst[0]=c;

for(i=1;i<=strlen(str);++i)
dst[i]=str[i-1];
dst[i+1]='\0';
}

ואז לקרוא לפונקציה ככה (הקצאה סטטית):

char dst[10];
strshr(c, str, dst);

או לחילופין (הקצאה דינמית):

char* dst = (char*)malloc(10);
strshr(c, str, dst);

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

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

פורסם
  • מחבר

סבבה, תודה.

פורסם

לדוגמה, אתה יכול לעשות ככה:

void strshr(char c, char* str, char* dst)
{
int i;

dst[0]=c;

for(i=1;i<=strlen(str);++i)
dst[i]=str[i-1];
dst[i+1]='\0';*********
}

כשהלולאה תסתיים i כבר יהיה שווה strlen(str) + 1 לא? כך שלהציב ב dst[i+1] יהיה שגיאה..

פורסם
  • מחבר

צודק.

ארכיון

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

דיונים חדשים