עבור לתוכן

שפת C: בעייה בהקצאות זכרון/ פויינטרים

Featured Replies

פורסם

שלום לכולם!

מבסגרת שיעורי הבית שלי נתקלתי בבעיה:

הנה חלק מתוכנית שכתבתי בשפת C



void main()
{
Monom** polynom;

readArr(polynom,&size);
}

void readArr(Monom** outArr, int* outSize)
{
Monom** arr;
int phsSize;

phsSize=1;
arr=(Monom**)malloc(1*sizeof(Monom*));
if(arr==NULL)
exit(1);

arr[numOfMonomsInArr]->coefficient=phsSize;
.
.
.
outArr=arr; <--
*outSize=numOfMonomsInArr;
}

monom: מבנה המכיל: coefficient, power מסוג מספרים שלמים.

בשורה האחרונה יש בעייה ורשום:

access violation writing location...

איך אני מתקן את הבעייה? איך אני יכול לבצע הצבה לתוך השדה של Monom?

תודה

פורסם

מה שעשית הוא להקצות מערך של מצביעים. הבעיה היא שלאחר ההקצאה, המערך שלך לא מאותחל - כל איבר במערך מצביע לא חוקי.

אתה צריך לדאוג לאתחל כל איבר במערך (ע"י עוד malloc).

פורסם
  • מחבר

אכן צדקת! עכשיו החלק הזה עובד, אבל עוד בעייה צצה בהמשך:

הוספתי עוד 2 שורות בקוד המקורי, וסימנתי חץ על השורה הלפני אחרונה, שם אני חושב שיש את הבעיה:

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

פורסם

העברות משתנים לפונקציות ב-C נעשות ע"י העברה by value. כלומר, כשאתה מעביר ערך כלשהו לפונקציה, הערך הזה מועתק לפרמטר.

מה זה אומר?

נניח שיש לך את הקוד הבא:

void foo(int x) {
x = 5;
}

int main() {
int y = 1;
foo(y);
printf("%d"\n",y);
}

היית מצפה שיודפס 5, אבל למעשה מודפס 1. הסיבה לכך היא שבקריאה לפונקציה, הערך של y מועתק למשתנה חדש בשם x, ואז כל שינוי ב-x לא ישפיע על y.

על מנת לשנות את המשתנה שמועבר, צריך להעביר מצביע, ככה:

void foo(int *x) {
*x = 5;
}

int main() {
int y = 1;
foo(&y);
printf("%d"\n",y);
}

יש מבין?

פורסם
  • מחבר

זה ברור לי.

אבל שמדובר במצביעים זה קצת יותר מבולגן, ובמצביע למצביע זה עוד יותר.


Monom** polynom;
readArr(polynom,&size);

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


void readArr(Monom** outArr, int* outSize)
{
Monom** arr;
.
.
.
outArr=arr;
}


outArr לא מקבל כרגע גם כן כתובת של מצביע למצביע (arr) ששניהם מצביעים מאותו סוג?

לי זה נראה שכן, אבל כנראה שזה לא, בגלל שהכתובת לא נשמרת ב- outArr.

פורסם

זה לא משנה מה הטיפוס.

אם הטיפוס של polynom הוא **Monom, אז על מנת להעביר אותו לפונקציה שתוכל לשים בו ערך אתה חייב שהפונקציה תקבל מצביע לטיפוס שלו, כלומר ***Monom, ואת ההשמה לבצע באמצעות outArr=arr*.

פורסם
  • מחבר

הבנתי! ושוב, אכן עובד. תודה.

אבל כמובן, בעיות נוספות כל פעם... שאלה נוספת, לא קשורה למערכים:

האם יש ב-C פונקציה כמו ה- cin.getchar שב- cpp? אני צריך לקבל קלט ארוך ו"למשוך" כל פעם תו אחד מהבאפר?

פורסם

...אין ל-cin פונקציה בשם getchar. יש סתם פונקציה בשם getchar שהיא ב-stdio.h (ולכן היא קיימת ב-C).

פורסם
  • מחבר

אופס, טעות שלי, התכוונתי ל cin.get.

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

בטוח שיהיו לי עוד שאלות בהמשך.

את תודה, שבוע טוב ולילה טוב,

מושיקו

פורסם
  • מחבר

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

ארכיון

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

דיונים חדשים