#c #memory
#c #память
Вопрос:
Я не могу очистить str
переменную, выделенную в ft_itoa_base()
функции. Ошибка pointer being freed was not allocated
.
void work_ptr_accuracy(t_args *args, char **return_str,
va_list *arg)
{
int size_accuracy;
char *str_tmp;
char *str;
unsigned long long int n;
str_tmp = NULL;
str = NULL;
if (args->accuracy != -1)
{
size_accuracy = args->accuracy;
n = va_arg(*arg, unsigned long long int);
str = ft_itoa_base(n, 16, LOWERCASE);
*return_str = ft_substr(str, 0, size_accuracy);
free(str);
str_tmp = ft_strjoin("0x", *return_str);
free(*return_str);
*return_str = str_tmp;
}
}
это ft_itoa_base()
char *ft_itoa_base(unsigned long long int value,
unsigned long long int base, int regist)
{
int len;
unsigned long long int digit;
char *return_str;
char *base_tmp;
base_tmp = get_register(regist);
if (value == 0)
return ("0");
len = 0;
digit = value;
ft_baselen(digit, base, amp;len);
if (!(return_str = (char *)malloc(sizeof(char) * (len 1))))
return (NULL);
return_str[len] = '';
while (digit)
{
return_str[--len] = base_tmp[digit % base];
digit /= base;
}
if (value < 0 amp;amp; base == 10)
return_str[0] = '-';
return (return_str);
}
это мой ft_substr()
/*
** Function: char *ft_substr
**
** Description: Allocates (with malloc(3)) and returns a substring
** from the string ’s’.
** The substring begins at index ’start’ and is of
** maximum size ’len’.
*/
char *ft_substr(const char *s, unsigned int start, size_t len)
{
unsigned int i;
unsigned int j;
char *str;
i = 0;
j = 0;
if (!s)
return (NULL);
if (start >= ft_strlen(s))
{
if (!(str = (char *)malloc(1)))
return (NULL);
str[0] = '';
return (str);
}
while (s[i] != s[start])
i ;
if (!(str = (char *)malloc((len * sizeof(char)) 1)))
return (NULL);
while (j < len amp;amp; s[i])
str[j ] = s[i ];
str[j] = '';
return (str);
}
Комментарии:
1. Я понятия не имею, что
ft_iota_base
это значит, но вы читали документы, чтобы узнать, нужно ли их использоватьfree
? Основываясь на этой ошибке, я предполагаю, что вам нужно очистить ее каким-то другим способом.2. Итак … Не делайте этого, хотя большинство / многие функции, которые возвращают указатель на что-либо, делают это с помощью
malloc
, это не обязательно. Некоторые функции возвращают указатель на статическую / глобальную переменную [которую вы не можете освободить — как вы выяснили]. Пример:localtime
возвращает указатель на статическую / глобальную область. Если [и я повторяю: если ] значение выделено, то единственным способом получить эту ошибку будет некоторая форма повреждения кучи, которая, в данном случае, должна быть выполненаft_substr
. Поскольку вы не опубликовали исходный кодft_substr
, я предполагаю, что это стандартная функция библиотеки. Если нет, опубликуйте всеft_*
функции.3. Основываясь на том, что нашел «Swift — TL; DR» :-), возможно, вам следует сделать (например)
if (value == 0) return NULL;
4. @CraigEstey Я думаю, идея заключалась в том, что
ft_itoa_base
никогда не следует возвращать нулевой указатель, освобождение одного было бы безопасным, но использование одного не было бы, и целое число всегда преобразуется в строковое представление. Найденный код, возможно, изменен для подачи иска с любым основанием вплоть до «Z»: P5. @Swift-FridayPie Да, я собирался добавить этот пункт в свой предыдущий комментарий, но для этого не хватило места. Прежде чем я смог добавить второй комментарий, появился ваш ответ, и пример кода охватил этот момент, поэтому [с решаемой проблемой] я не видел необходимости повторять одно и то же.
Ответ №1:
Плохой дизайн ft_itoa_base
. return ("0")
возвращает указатель на статически выделенный массив, состоящий из двух символов (‘0’ и »). Это невозможно free
изменить.
Сравните с этой реализацией lwang <marvin@42.fr>
#include <stdlib.h>
#include <stdio.h>
int ft_abs(int nb)
{
if (nb < 0)
nb = -nb;
return (nb);
}
char *ft_itoa_base(int value, int base)
{
char *str;
int size;
char *tab;
int flag;
int tmp;
flag = 0;
size = 0;
tab = "0123456789ABCDEF";
if (base < 2 || base > 16)
return (0);
if (value < 0 amp;amp; base == 10)
flag = 1;
tmp = value;
while (tmp /= base)
size ;
size = size flag 1;
str = (char *)malloc(sizeof(char) * size 1);
str[size] = '';
if (flag == 1)
str[0] = '-';
while (size > flag)
{
str[size - 1] = tab[ft_abs(value % base)];
size--;
value /=base;
}
return (str);
}