עבור לתוכן

הבנת שגיאה בvalgrind ב- c

Featured Replies

פורסם

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

strcmp וגם ב- strcpy

יבאתי קודם את הספריות הבאות:

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

כשאני מפעיל valgrind מופיע לי:

==10166== Invalid write of size 1
==10166== at 0x40290C0: strcpy (mc_replace_strmem.c:311)
==10166== by 0x80486B1: register_entry (task.c:99)
==10166== by 0x80484C0: main (task.c:28)
==10166== Address 0x41bf072 is 6 bytes after a block of size 4 alloc'd
==10166== at 0x4028876: malloc (vg_replace_malloc.c:236)
==10166== by 0x8048680: register_entry (task.c:94)
==10166== by 0x80484C0: main (task.c:28)


==10166== Invalid read of size 1
==10166== at 0x40299DF: strcmp (mc_replace_strmem.c:538)
==10166== by 0x8048629: register_entry (task.c:81)
==10166== by 0x80484D8: main (task.c:29)
==10166== Address 0x41bf06c is 0 bytes after a block of size 4 alloc'd
==10166== at 0x4028876: malloc (vg_replace_malloc.c:236)
==10166== by 0x8048680: register_entry (task.c:94)
==10166== by 0x80484C0: main (task.c:28)

למה מופיעות השגיאות האלו?

פורסם

הוא בדיוק אומר לך:

Address 0x41bf072 is 6 bytes after a block of size 4 alloc'd

אתה ניגש לבית שנמצא 6 מקומות אחרי זכרון שהוקצה בגודל 4 בלבד.

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

פורסם
  • מחבר

אוקיי, תודה.

אולי הבנתי מה הבעיה אך לא יודע איך לפתור אותה:

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

char * last_name

בתוך הפונקציה רציתי להקצות מקום בheap בגודל של last_name ושם ליצור העתק של המחרוזת.

עשיתי זאת כך:

 char* newLastname=(char*)malloc(sizeof(last_name));

וההשוואה בוצעה כך:

 strcpy( newLastname, last_name );

עכשיו, יכול להיות שכשכתבתי

 char* newLastname=(char*)malloc(sizeof(last_name));

הוקצה מקום בגודל של פוינטר?

ניסיתי גם להוסיף * לפני last_name כדי לקבל את הערך ואז את הגודל של הערך אבל עדיין אותה בעיה.

אשמח לפתרו לבעיה..

פורסם

sizeof על מצביע מחזירה את הגודל של המצביע, לא את הגודל של הזכרון שהוא מצביע עליו.

בשביל לדעת את הגודל של מחרוזת תשתמש ב-strlen (ואל תשכח להוסיף 1 בשביל ה-null terminator).

פורסם
  • מחבר

רק כדי לוודא שהבנתי- בגלל שגודל של char הוא 1,

מספיק להקצות גודל של אורך המחרוזת?

תיקנתי את מה שאמרת, השגיאות פחתו בהרבה אבל עדיין יש כמה ולא ברור לי למה.

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

   entry *register_entry(entry* list, char * last_name){
entry *newEntry=NULL; /* the returnedEntry**/
entry* currEntry=list;
entry* prevCurr=NULL;/* the entry before the current one**/
int flag=0;
while(currEntry!=NULL){

if( strcmp(currEntry->lastname,last_name)==0){
currEntry->count++;
flag=1;
newEntry=currEntry;
break;
}
prevCurr=currEntry;
currEntry=currEntry->next;
}

if(flag==0){/* last name not exist**/

newEntry=(entry*)malloc(sizeof(struct entry));
char* newLastname=(char*)malloc(strlen(last_name));
newEntry->count=1;
newEntry->lastname=newLastname;
newEntry->next=NULL;
/*copyLastname(last_name,newLastname);**/
strcpy( newLastname, last_name );


if(prevCurr!=NULL) /* need to connect the new entry to the prev entry**/
prevCurr->next=newEntry;


}
return newEntry;

}

 Invalid read of size 1
==13529== at 0x40299DF: strcmp (mc_replace_strmem.c:538)
==13529== by 0x8048625: register_entry (task.c:115)
==13529== by 0x80484D8: main (task.c:29)
==13529== Address 0x41bf072 is 0 bytes after a block of size 10 alloc'd
==13529== at 0x4028876: malloc (vg_replace_malloc.c:236)
==13529== by 0x8048697: register_entry (task.c:128)
==13529== by 0x80484C0: main (task.c:28)

פורסם
  • מחבר

אכן זאת הבעיה..תודה!

ארכיון

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

דיונים חדשים