Я знаю, что этот вопрос существует и в других местах, как:Указатель освобождения не был выделен массив строк в C
pointer being freed was not allocated in C error: pointer being freed was not allocated
, но я все еще очень смущен. Ошибки, по-видимому, связаны с такими вещами, как «изменение исходного указателя, возвращаемого malloc» и «отказ от malloc до освобождения». Я просто не понимаю, как эти причины относятся к моей программе.
Я пишу динамически выделенный массив строк:
#include <stdio.h>
#include <stdlib.h>
#define NLETTERS 25
typedef struct {
char** array;
size_t used;
size_t size;
} array_t;
array_t* initArray(size_t initialSize) {
array_t* a = malloc(sizeof(array_t));
a->array = malloc(initialSize*sizeof(char*));
a->used = 0;
a->size = initialSize;
int i;
for(i = 0; i < initialSize; i++) {
a->array[i] = malloc(sizeof(char) * NLETTERS);
}
return a;
}
void insertArray(array_t *a, char* element) {
if (a->used == a->size) {
a->size *= 2;
a->array = realloc(a->array, a->size * sizeof(char*));
int i;
for(i = (int)a->used; i < a->size; i++) {
a->array[i] = malloc(sizeof(char) * NLETTERS);
}
}
a->array[a->used++] = element;
}
void freeArray(array_t *a) {
int i;
for(i = 0; i < a->size; i++) {
free(a->array[i]);
}
free(a->array);
free(a);
a->array = NULL;
a->used = a->size = 0;
}
void print_array(array_t *a) {
int i;
for(i = 0; i < a->size; i++) {
printf("%s\n", a->array[i]);
}
}
int main(int argc, const char * argv[]) {
array_t *a;
a = initArray(2);
insertArray(a, "hello");
insertArray(a, "how are you");
print_array(a);
insertArray(a, "yup");
insertArray(a, "you know it");
print_array(a);
freeArray(a);
return 0;
}
При попытке «бесплатно», я получаю ошибку: «указатель освобождения не было выделено» право на
free(a->array[0])
в первой итерации цикла for в freeArray();
Справка была бы принята с благодарностью.
Вы полагаете, что мой перераспределить неверна? С чем это должно измениться? Я не совсем понимаю, какое исправление находится под этой ссылкой. – Chris
Обратите внимание, что в 'insertArray()' у вас есть idiom 'old_ptr = realloc (old_ptr, new_size);'. Это плохо. Если (когда!) 'Realloc()' fail, вы пропустите память, потому что 'old_ptr' переписан с помощью NULL, поэтому вы больше не можете освобождать старую память, даже если она все еще выделена. Используйте 'new_ptr = realloc (old_ptr, new_size); if (new_ptr == NULL) {... сообщить об ошибке и т. д.} old_ptr = new_ptr; '(и обычно также' old_size = new_size; 'тоже). –