[英]Valgrind error: invalid read/write when malloc
Valgrind在下面的代碼中給出了以下錯誤: 無效寫入大小8:地址XX是一個大小為33的塊中的32字節alloc'd
/*The function allocate memory and clean it for further use.*/
static void *ft_mal(size_t size)
{
void *ret;
char *tmp;
ret = malloc(size); /*LINE WITH ERROR*/
if (!ret)
return (NULL);
tmp = ret;
while (size) {
*tmp = 0;
tmp++;
size--;
}
return (ret);
}
我在下面的代碼中使用此函數,其中在注釋行上還有兩個無效的寫入大小為8的錯誤:
/*Splits a string into an array of strings*/
char **ft_splt(const char *s, char c)
{
char **ret;
char *str;
int i;
i = ct_wd(s, c);
ret = (char **)ft_mal(sizeof(*ret) * i + 1);
str = (char *)ft_mal(sizeof(*str) * ct_c(s, c) + i);
i = 0;
while (*s) {
while (*s && *s == c)
s++;
ret[i++] = (*s ? str : '\0'); /*LINE WITH ERROR*/
while (*s && *s != c)
*str++ = *s++;
if (*s)
*str++ = '\0';
}
ret[i] = 0; /*LINE WITH ERROR*/
return (ret);
}
我不明白為什么它產生錯誤,因此也不知道如何解決它們。 因此,當我釋放mallocs時,我有一個錯誤。
如何解決這些無效的讀/寫錯誤?
編輯:
根據需要,我提供更多代碼。 ct_wd和ct_c分別計算字符串參數中的字數和字符數,以便創建正確大小的malloc。
static int ct_wd(const char *s, char c)
{
int nb;
nb = 0;
while (*s) {
while (*s && *s == c)
s++;
while (*s && *s != c)
s++;
nb = (*(s - 1) != c ? nb + 1 : nb);
}
return (nb);
}
static int ct_c(const char *s, char c)
{
int nb;
nb = 0;
while (*s) {
if (*s != c)
nb++;
s++;
}
return (nb);
}
這是一個main.c示例:
int main()
{
char s[] = "lut:les:enf:? ";
char **ret;
int i = 0;
ret = ft_splt(s, ':');
while (ret[i]) {
printf("[Resultat :]\n");
i++;
}
/* free all malloced pointer */
return (0);
}
編輯:解決方案
如下所述,有一個錯誤:
ret = (char **)ft_mal(sizeof(*ret) * i + 1);
應該是:
ret = (char **)ft_mal(sizeof(*ret) * (i + 1));
執行時我仍然有一個段錯誤。 似乎刪除此行:
ret[i] = 0;
刪除了valgrind錯誤和segfault。 我理解這行不是必要的,因為ft_mal已經清理了內存,但我真的不明白為什么這兩者都在valgrind中產生了寫錯誤並使我陷入了錯誤。
向后工作:
最后的錯誤很簡單。 我想你打算ret
是數組char *
是零終止。 但你這樣分配它:
ret = (char **)ft_mal(sizeof(*ret) * i + 1);
如果你想要一個終止null
條目,你需要i + 1
個大小*ret
條目,即
ret = (char **)ft_mal(sizeof(*ret) * (i + 1));
前面的錯誤更難。 這一行:
ret[i++] = (*s ? str : '\0'); /*LINE WITH ERROR*/
令人困惑。 ret[i++]
似乎是一個char *
。 但你似乎在復制char
。 你在這里做什么意思? 使用-Wall
編譯時會發生什么? 我打賭你看到了警告。
這一行:
ret = malloc(size); /*LINE WITH ERROR*/
看起來不太可能產生你建議的valgrind錯誤。 我建議使用-O0 -g -Wall
編譯,並在修復其他位后再次嘗試,並仔細檢查行號。
它會產生free()
錯誤,因為你永遠不會free()
任何東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.