עבור לתוכן

שאלה מתחילים על מצביעים

Featured Replies

פורסם

void add_line(int **data,int &lines, int *info[MAX]) {
int input[MAX],
size=1,
counter=0,
freeline;


freeline=check(data,lines);


cin >> input[counter];
if (input[counter]==0)
return;
while (input[counter!=0]) {
// if (input[0]==0)
// return;
counter++;
if (size<counter)
size=size*2;
cin >> input[counter];
}


data[freeline] = new (std::nothrow) int[size];
if (data[check(data,lines)] == NULL) {
cout << "Cannot allocate memory\n";
exit(0);
}

הקריסה בעת הקצאת הזיכרון, ז"א:

data[freeline] = new (std::nothrow) int;

freeline=0, size=1 , איך מקצים את הזיכרון בצורה נכונה?

פורסם

בוא נתחיל ממשהו יותר בסיסי.

- מה הקוד הזה אמור לעשות?

- היכן הפונקציה check? מה היא עושה?

פורסם
  • מחבר

הקוד הוא חלק מתכנית גדולה מאוד (שרובה עדיין בכתיבה), היא בונה סוג של DATABASE דינמי בזכרון, שהמשתמש יכול להוסיף בו שורות לגרוע שורות וכו....

הפונק' check בודקת מהי השורה הפנויה הראשונה בDATABASE הקיים, ובמקרה הנ"ל מחזירה 0 וזה נבדק בDEBUG (כי עדיין שום שורה לא נוצרה בDATABASE...).

בסופו של דבר: data[freeline] = new (std::nothrow) int;

הופך ל: data[0] = new (std::nothrow) int size[1];

פורסם

טוב, קל זה לא יהיה.

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

1)

input[counter!=0]

- סביר להניח שזה לא הביטוי שרצית לבדוק בתנאי העצירה.

2) מה קורה עם counter עובר את MAX בשלב כלשהו?

3) אתה מנסה להקצות

data[freeline]

אבל לא ראיתי בשום מקום שהקצית את data.

פורסם
  • מחבר

תודה, כל הערות נכונות. :xyxthumbs:

פורסם
  • מחבר

היי, רק עכשיו יצא לי לשבת על זה קצת...

אשמח לביאור בקשר להערה 3..

*data[] שקול ל **data (אם אני מבין נכון...)

ובעצם כשאני מקצה data[0]=blablabla אני מקצה למצביע הראשון מתוך רשימת המצביעים של data את blablabal....

למה ואיך עליי להקצות את data עצמו?

פורסם
  • מחבר

טוב לא יודע מה הייתה הכוונה בהערה אבל פשוט שיניתי בהגדרת דאטא במקום: *data[] ל *data[0] והכל עובד פרפקט... :-\

פורסם

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

נגיד שיש לך משהו כמו int* array. אתה יודע שאתה חייב להקצות את array כדי לגשת לתא כלשהו במערך.

כנ"ל לגבי int** data. לפני שאתה מקצה את המערך data, אין משמעות לביטוי data[0].

פורסם
  • מחבר

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

שאלתי היא, נגיד שיש לי **data שעליו אני רוצה לעבוד.

אני רוצה בסופו של דבר מערך דו מימדי של INTים בגודל 5.

אני מבין שהקצאה כל פעם: data[0]=new int[5]; t לא מספיקה.... (אח"כ במקום ה0 לרשום 1 וכך הלאה..).

איך אני מקצה את DATA עצמו?

פורסם

אתה רץ בלולאה על המערך ומקצה זיכרון לכל תא.

פורסם
  • מחבר

אבל איך אני יכול להרצת זיכרון לכל תא אם אני עדיין לא יודע מהם התאים וכמה יהיו?? :s05:

הרי כל הרעיון זה, שהכל דינמי..

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

אני רוצה להכניס כל פעם שורה כזאת למערך הדו מימדי... (DATA**

פורסם

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

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

אם עוד לא למדתם רשימות מקושרות ו/או אם קיימת דרישה להשתמש דווקא במערך דו-מימדי, אזי הפתרון של realloc הוא מתאים - מקצים מראש מספר שורות מסוים, ואם יש חריגה - מכפילים את הגודל ומקצים מחדש.

פורסם

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

  • 2 שבועות מאוחר יותר...
פורסם
  • מחבר

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

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

realloc

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

הפתרון היה כדלקמן (מערך דו מימדי שגודל כל פעם בשורה):

1. יוצרים data_temp בגודל SIZE+1.

2. מכניסים את השורה החדשה לdata_temp[size+1] d

3. מעתיקים את כל DATA לתוך DATA_TEMP וכך יש לנו מערך חדש עם השורה החדשה בDATA_TEMP.

4. מוחקים את DATA.

5. יוצרים DATA בגודל SIZE+1.

6. מעתיקים את DATA_TEMP ל DATA.

7. מוחקים את DATA_TEMP.

והופה טרללה יש לנו מערך חדש עם עוד שורה.

ארכיון

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

דיונים חדשים