עבור לתוכן

הגדרת מערך דינאמי בC

Featured Replies

פורסם

שלום

יש לי קצת בעיה עם הגדרת מערך דינאמי של מבנים בc

נניח ויש את המבנה הבא


typedef struct
{
int id;
char name[24];
.
.
.
}kid

ועכשיו אני רוצה להגדיר מערך דינאמי של ילדים כאלה, אז רשמתי ככה:


kid *w;
w= (kid*) malloc (sizeod(kid));

במצב שנוצר משום מה הוא בונה לי מספר לא ברור של תאים שאני יכול להתייחס אליהם כאשר אני רושם לדוג' kid[60].id

השאלה היא אם לא היה יותר נכון להגדיר את זה ככה:


kid **w;
w= (kid**) malloc (sizeod(kid));

ואז להגדיר כל תא בנפרד ע"י


w[next] = (kid*) malloc (sizeof(kid));

בכל מקרה, אני צריך גם דרך לדעת מהו גודל המערך, בלי משתנה עזר, אז ניסיתי לעשות כך


size = sizeof(w[0]) / sizeof(w);

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

בתודה מראש

פורסם

הקוד הזה:

malloc(sizeof(kid))

מקצה מקום בזכרון ל-kid אחד בלבד. בשביל להקצות מערך בן n איברים אתה צריך

malloc(sizeof(kid) * n)

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

שים לב שגם הקוד שלך שמקצה מערך של מצביעים לא טוב - אתה מקצה מערך בגודל של kid, שאין לו שום קשר לגודל של מצביע.

פורסם
  • מחבר

שוב שלום לכולם (וזה הזמן להודות לכם על התשובות לכל החפירות שאני שולח פה בזמן האחרון)

יש לי קצת בעיה עם הקצאה דינאמית, אני מתעסק במבנה כלשהו, נניח:


typedeg struct
{
int num:
char str[30];
kid *k;
}parent

ההגדרה של ההורה היא כך parent *p כלומר יש מערך דינאמי של הורים

עכשיו כפי שאפשר לראות, אחד השדות הוא מערך דינאמי של איזשהו מבנה אחר (kid), את השדות ה"רגילים" אני מצליח למלא כמו שצריך ע"י p[0].num = 0 לדוג', אבל השדה של הkid מתעקש לעשות בעיות, הוא גם אמור להיות מערך דינאמי וכשאני מנסה להגדיר אותו כל הזיכרון מתקלקל, דבר זה מוזר מאוד עקב העובדה שכל המבנה של ההורים מלכתחילה מוגדר בעצמו כמערך דינאמי והכל מצליח, זה לא אמור להיות אותו הדבר?? אני עושה זאת ע"י השורה


p[i].k = (kid*) maloc (sizeof(kid));

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

האם אני מפספס כאן איזושהי כוכבית או משהו אחר?, ד"א, בהתחלה עשיתי את כל ההשמות הללו בפונקציות, אבל כשראיתי שזה לא הולך רשמתי את זה בmain וזה עדיין הורס את הזיכרון, אשמח אם מישהו יוכל להאיר את עיניי :)

פורסם

אל תפתח שני ת'רדים על אותו נושא. איחדתי את הת'רדים שלך.

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

חוץ מזה, יעזור אם נבין איך הקצית את מערך ההורים.

פורסם
  • מחבר

תודה על ההבהרות,

את מערך ההורים הקצאתי כך -


p= (parent*) malloc (sizeof(parent));

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

אבל זה לא הקטע, גם לגבי kid, זה לא משנה אם אני מגדיר ממנו 1 או 10, הוא הורס לי את כל הזיכרון של שאר השדות וזה מה שאני מנסה להבין...

פורסם

ואיך אתה עושה realloc?

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

באמת יעזור אם תביא את הקוד המלא.

פורסם
  • מחבר

המבנים (כמובן שנחסכו פה כמה שדות, זה לא ממש משנה)


typedeg struct
{
char name[30]
int age;
}kid;

typedeg struct
{
int num:
char str[30];
kid *k;
}parent

הקצאה התחלתית להורים


p= (parent*) malloc (sizeof(parent));

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


void addNewParent(Parent *p, int size)
{
int num;
char temp[MAX];
if(size) //making one more item in the array for the next Parent
p= (Parent*) realloc (p,(size+1)*sizeof(Parent));

scanf("%d", &p[size].num)
.
.
.
עוד קליטת נתונים "רגילים"

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


p[size].k = (kid*) maloc (sizeof(kid));

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

(ואז מגדיל את size, שזה משתנה שבעצם אומר כמה יש במערך בכל רגע, סתם אם תהית, והוא מתחיל מ0 ככה שזה בסדר שהrealloc עושה size+1 אבל אני קולט נתונים למקום size, לפחות ככה נראה לי :) לא חושב שזו הבעיה)

פורסם

ואיך אתה יודע שדווקא ה-malloc הוא הבעייתי? ייתכן שזה רק סימפטום של בעיה אחרת.

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

פורסם
  • מחבר

מה שרשמתי שם זה הקוד המלא, הכל נמצא בהערות פרט להקצאות הדינאמיות, ככה שאפילו אין קליטת נתונים, סתם הקצאה של הורה, עכשיו כל עוד אני לא מנסה להקצות גם ילד - הוא נותן לי להגדיר כמה שבא לי, ואני יכול לראות אותם בwatch והכל בסדר איתם ברגע שהmalloc של הילדים נכנס לתמונה הכל מתהפך

פורסם

הנה הבעיה שלך:

    p= (Parent*) realloc (p,(size+1)*sizeof(Parent));

הפעולה הזו רק משנה את המשתנה המקומי p. המשתנה שהועבר לפונקציה addNewParent לא ישתנה, ובעצם יצביע עדיין למקום בזכרון לפני ה-realloc (זו בעיה של העברת משתנים לפונקציה, ולא קשור ל-malloc/realloc).

פורסם
  • מחבר

רב תודות לך יא שניצל ;)

עד התקלה הבאה...

ארכיון

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

דיונים חדשים