עבור לתוכן

שינוי גודל של סטרינג - realloc - שפת C

Featured Replies

פורסם

שלום,

אני מנסה לקבל מהמשתמש סטרינג. במידה והוא מכניס משפט גדול מהגודל שהוקצה למשתנה, אני מנסה לבצע את הפעולה הבאה:

p = (char *) realloc (p,sizeof(char)*strlen(gets(arr)));

כל התוכנית:

#include<stdio.h>#include<conio.h>
#include<string.h>
#include<alloc.h>
#include<stdlib.h>

main(){
int i;
char arr[] = "aaaaa",*p=arr;
puts(arr);
p = (char *) realloc (p,sizeof(char)*strlen(gets(arr)));
puts(arr);
}

האם זה באמת מגדיל לי אותו ללא דריסת זכרון?

תודה מראש.

פורסם

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

אפשר לקרוא לrealloc רק על איזור שהוקצה קודם לך ע"י malloc (או calloc)

פורסם

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

פורסם
  • מחבר

היא לא נכשלת.

ע"י realloc ניתן גם להקצות זכרון:

int *ip;
ip = (int*) realloc(NULL,sizeof(int)*5)

פורסם

זה שזה במקרה עובד, לא אומר שהקוד שלך תקין או בטוח.

למעשה ברגע שעשית gets(arr) וקראת יותר מהאורך המקסימלי בarr - כבר ביצעת משהו לא תקין, ואין ממש משמעות לשאר הדברים שתעשה (כן realloc או לא).

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

פורסם

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

או לקרוא את כל השורה אבל להגדיל את את איזור הזיכרון במהלך הקריאה, בדומה למה שעושה std::string

הנה דוגמה אפשרית ולשואל המקורי זאת דוגמה לשימוש נכון ב-realloc

מי שיקרא לפונקציה יהיה חייב לשחרר בעצמו את הזיכרון ע"י free


[LEFT]
#include <stdio.h>
#include <stdlib.h>

char* fgetline(FILE* fp)
{
char c;
char* line;
char* new_line;
size_t len = 0, alloc_len = 20;

/* allocate buffer */
if ((line = (char*) malloc(alloc_len)) == NULL)
return NULL;

while ((c = fgetc(fp)) != '\n' && c != EOF) {
line[len] = c;

/* check if buffer full and reallocate if needed*/
if (++len == alloc_len) {
alloc_len *= 2;
if ((new_line = (char*) realloc(line, alloc_len)) == NULL) {
free(line);
return NULL;
}
line = new_line;
}
}

line[len] = '\0';
return line;
}
/*--------------------------------------------------------*/
[/LEFT]




ארכיון

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

דיונים חדשים