Существует несколько проблем:
char **alloc_str(char **existing, const char *add)
{
int length = 0; //find the length of the array
for (; existing[length]; length++)
{
}
//allocate memory to copy array array
char **existing_c = (char **)calloc(length + 2, sizeof(char *));
for (int i = 0; i < length; i++) //copy original array into new array
{
existing_c[i] = existing[i];
}
////////////////////////////////////
//possible memory leak error
strncat(existing_c, add, sizeof(existing_c) - strlen(existing_c) - 1);
existing_c[sizeof(existing_c)-1] = '\0';
//possible memory leak error
strncpy(existing, existing_c, sizeof(existing - 1));
s_copy[sizeof(destsize)-1] = '\0'; //error here
////////////////////////////////////
free(existing);
return existing_c;
}
Часть, отмеченная ////////////////////////////////////
, не имеет особого смысла.
Вы выделили массив указателей.Не относитесь к этому как к строке.Это не строка.Вместо этого просто назначьте новый указатель на конец массива и снова добавьте терминатор.
existing_c[length] = add;
existing_c[length+1] = NULL;
С этим терминатором вы можете использовать обычный malloc
вместо calloc
, поскольку вы все равно назначаете все элементы массива.
Помимо проблемы с выделением, у вас есть еще одна утечка памяти:
void free_array(char **strings) //free's data in array, should be fine
{
int length = 0;
for (; strings[length]; length++)
{
}
strings = (char **)calloc(length + 2, sizeof(char *));
}
Вы передаете указатель на массив указателей.Этот массив занимает некоторую память, которую вы выделили с calloc
ранее.Затем вы выделяете немного больше памяти и присваиваете адрес локальной переменной string
.
Это имеет две проблемы:
- Память, которая была выделена ранее, не освобождается.
- Память, которую вы выделяете в этой функции, недоступна за пределами этой функции.
В конце ваша функция free_array
ничего не освобождает, но потребляет больше памяти.
Другая проблема может присутствовать со строками, которые вы храните в этом массиве.В вашем примере вы используете строковые литералы.Это статические объекты, и их не нужно освобождать.
Если вы будете использовать свои функции для хранения указателей и на динамически размещаемую строку, вам также необходимо позаботиться о выделении и освобождении строк.