פורסם: 09/06/2015 - 21:55
נושא ההודעה: אורך מחרוזת ב C
|
שלום לכולם
האם יש דרך לדעת מה האורך של מחרוזת מבלי לבדוק עם strlen או ללכת כל עוד לא רואים /0
לצורך העיניין אם מועבר לי פוינטר של מחרוזת ואני רוצה לדעת מה האורך שהmalloc מקצה לו
בלי להשתמש בstrlen או ב/0
תודה מראש לכולם
|
|
חזרה לתוכן הדיון |
פורסם: 09/06/2015 - 22:04
נושא ההודעה:
|
אין קשר בין האורך שmalloc מקצה ובין מיקום הnul בסיום המחרוזת.
|
|
חזרה לתוכן הדיון |
פורסם: 09/06/2015 - 22:19
נושא ההודעה:
|
שאלה מעניינת (לא יודע את התשובה בעצמי) - הלא free צריך לדעת כמה זכרון הוקצה מראש, אז המידע הזה חייב להיות שמור במקום מסוים. השאלה היא האם יש דרך לגשת אליו?
לפי הדיון כאן - http://stackoverflow.com/questions/1518711/how-does-free-know-how-much-to-free - התשובה היא שזה לא חלק מהתקן, ולפחות בחלק מהמימושים יש אפשרות לגשת למידע הזה.
|
|
חזרה לתוכן הדיון |
פורסם: 09/06/2015 - 23:44
נושא ההודעה:
|
בחלק מהמימושים של malloc הפויינטר שאתה מקבל בעצם מצביע 4 בייטים קדימה,
ובאינדקס 1- (אם זה אניט...) נשמר הגודל.
גיליתי את זה בדרך הקשה כשהייתה לי לולאה שרצה מהסוף להתחלה ופיספסה ב 1...
התוכנית קרסה כשניסיתי להחזיר את הזיכרון (לפעמים), valgrind עזר לי בסוף....
אני מתכנת גרוע
אבל בחיים אל תכתוב קוד שסומך על זה!!!!!!!!
סתכל פה:
http://stackoverflow.com/questions/4688041/good-c-string-library
|
|
חזרה לתוכן הדיון |
פורסם: 10/06/2015 - 06:48
נושא ההודעה:
|
אם אתה זה שמקצה את הזיכרון אז אתה גם יודע כמה הקצאת לא?
כמו שנאמר כאן אין קשר בין אורך החרוזת בפועל לבין הזיכרון שהוקצה ע"י malloc.
|
|
חזרה לתוכן הדיון |
פורסם: 10/06/2015 - 07:10
נושא ההודעה:
|
המחרוזת גם יכולה להיות מוקצה על המחסנית בכלל.
|
|
חזרה לתוכן הדיון |
פורסם: 10/06/2015 - 10:17
נושא ההודעה:
|
אפשרות שימושית בהרבה פרוייקטים היא תשתית שמשתמשת בסטראקטים של פוינטר וגודל (ובמקרה של מחרוזת אפשר אפילו גודל מלא וגודל טקסט ממשי אם זה ממש הכרחי), מקצה מחרוזות דרך פונקציה של התשתית הזו ומספקת פונקציות מתאימות לטיפול במחרוזות.
|
|
חזרה לתוכן הדיון |
פורסם: 10/06/2015 - 11:06
נושא ההודעה:
|
הנה דוגמא לקוד שלא מסתמך על גישה ישירה לגדלים ומיקומים בזיכרון ונותן אלוקציה עם גודל נגיש :
קוד: |
typedef struct buffer {char ptr[0]; size_t *size} buffer_t;
void *b_malloc(size_t size)
{
buffer_t *buff = malloc(size+sizeof(buffer_t));
return buff->ptr;
}
size_t b_size(void *ptr)
{
buffer_t buff * = container_of(ptr, buffer_t, ptr);
return buff->size;
}
|
הקוד הזה מניח פוינטר שהוקצה באמצעותו, כדי להוסיף בדיקה של זה אפשר להשתמש באיזה מספר-קסם שיוכנס לתחילת הבאפר (עם או בלי שדה נוסף בסטראקט)
|
|
חזרה לתוכן הדיון |
פורסם: 10/06/2015 - 11:27
נושא ההודעה:
|
סליחה, ההגדרה של הסטראקט אמורה להיות הפוך :
קוד: |
typedef struct buffer {size_t size; char ptr[0];} buffer_t;
|
|
|
חזרה לתוכן הדיון |
פורסם: 10/06/2015 - 16:57
נושא ההודעה:
|
Anonymous : | הנה דוגמא לקוד שלא מסתמך על גישה ישירה לגדלים ומיקומים בזיכרון ונותן אלוקציה עם גודל נגיש :
קוד: |
typedef struct buffer {char ptr[0]; size_t *size} buffer_t;
void *b_malloc(size_t size)
{
buffer_t *buff = malloc(size+sizeof(buffer_t));
return buff->ptr;
}
size_t b_size(void *ptr)
{
buffer_t buff * = container_of(ptr, buffer_t, ptr);
return buff->size;
}
|
הקוד הזה מניח פוינטר שהוקצה באמצעותו, כדי להוסיף בדיקה של זה אפשר להשתמש באיזה מספר-קסם שיוכנס לתחילת הבאפר (עם או בלי שדה נוסף בסטראקט) |
יש כאן לפחות שלוש שגיאות (השניה חמורה ממש):
1. אתה מקצה בגודל של buffer_t שמכיל size ומוסיף לגודל את size שוב. מיותר.
2. אתה לא מאתחל את size. אבל הפונקציה b_size מחזירה את הזבל שכנראה יש בשדה.
3. אתה לא בודק אם ה-malloc הצליח (כאן אתה בחברה טובה )
|
|
חזרה לתוכן הדיון |
פורסם: 10/06/2015 - 17:01
נושא ההודעה:
|
Anonymous : | Anonymous : | הנה דוגמא לקוד שלא מסתמך על גישה ישירה לגדלים ומיקומים בזיכרון ונותן אלוקציה עם גודל נגיש :
קוד: |
typedef struct buffer {char ptr[0]; size_t *size} buffer_t;
void *b_malloc(size_t size)
{
buffer_t *buff = malloc(size+sizeof(buffer_t));
return buff->ptr;
}
size_t b_size(void *ptr)
{
buffer_t buff * = container_of(ptr, buffer_t, ptr);
return buff->size;
}
|
הקוד הזה מניח פוינטר שהוקצה באמצעותו, כדי להוסיף בדיקה של זה אפשר להשתמש באיזה מספר-קסם שיוכנס לתחילת הבאפר (עם או בלי שדה נוסף בסטראקט) |
יש כאן לפחות שלוש שגיאות (השניה חמורה ממש):
1. אתה מקצה בגודל של buffer_t שמכיל size ומוסיף לגודל את size שוב. מיותר.
2. אתה לא מאתחל את size. אבל הפונקציה b_size מחזירה את הזבל שכנראה יש בשדה.
3. אתה לא בודק אם ה-malloc הצליח (כאן אתה בחברה טובה ) |
אתה צודק לגבי 2 ו-3 זו היתה רק הדגמה. לגבי אחד אתה טועה, ההקצאה צריכה להכיל את הזיכרון שהמשתמש יקבל, ושיתחיל מ buff.ptr ועוד גודל הסטראקט עצמו (שכרגע הוא size_t אבל יכולים להיות בו עוד איברים).
|
|
חזרה לתוכן הדיון |
פורסם: 11/06/2015 - 16:01
נושא ההודעה:
|
container_of הוא מקרו של הקרנל
יש לעשות casting
קוד: |
buffer_t *buff = (buffer_t*)ptr
|
|
|
חזרה לתוכן הדיון |
פורסם: 11/06/2015 - 16:24
נושא ההודעה:
|
Anonymous : | container_of הוא מקרו של הקרנל
יש לעשות casting
קוד: |
buffer_t *buff = (buffer_t*)ptr
|
|
זה קאסטינג לא נכון, אם כבר :
קוד: |
/* the correct decleration of buffer_t */
typedef struct buffer {size_t size; char ptr[0];} buffer_t;
buffer_t *buff = (buffer_t*)ptr-(sizeof(buffer_t);
|
|
|
חזרה לתוכן הדיון |
|