Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.74.54] |
|
Сообщ.
#1
,
|
|
|
Добрый день.
Требуется помощь с увеличением памяти, выделенной для массива указателей на С-строку. Задача такова: изначально выделяем немного памяти, а по ходу цикла понимаем, что памяти выделили мало, делаем до-выделение (через realloc()) и продолжаем пихать в наш массив указателей строчку. Суть в том, что мы на этапе компиляции не знаем значение real_life_max (но для примера я взял 350). #include <stdio.h> void p2p() { const char *sample_str = "abc"; const int initial_max = 50; // изначально предполагаем, что этого хватит const int real_life_max = 350; // жизнь показала, что нужно вот столько char **my_array = (char**)calloc(initial_max, sizeof(char)); // выделяем предполагаемый минимум // программа начинает работать в жесткой реальности for (int i = 0; i < real_life_max; i++) { if (i >= initial_max) // принимаем решение увеличивать выделенную память { char **tmp = (char**)realloc(my_array, sizeof(char) * 2); // my_array = tmp; } my_array[i] = (char*)malloc(8); // тут не уверен, надо ли выделять память на строку в массиве, на массив и так выделили calloc()-ом strcpy(my_array[i], sample_str); } //free(); } int main(void) { p2p(); return 0; } По факту получаю ошибку Unhandled exception at 0x77910E23 (ntdll.dll) in tstmem.exe: 0xC0000374: Куча была повреждена (parameters: 0x7794E930). windows 10, x64; MSVS 2017 Помогите, пожалуйста, с выделением памяти. |
Сообщ.
#2
,
|
|
|
Цитата barberan @ Помогите, пожалуйста, с выделением памяти. На смотри. Чутка поправил твой пример: #include <stdio.h> #include <stdlib.h> #include <string.h> void dump(char **array, size_t len) { for(size_t i=0; i<len; i++) printf("%03d : %s\n",i,*(array+i)); } void p2p() { const char *sample_str = "abc"; const size_t initial_max = 50; // изначально предполагаем, что этого хватит const size_t real_life_max = 350; // жизнь показала, что нужно вот столько size_t allocated = initial_max; char **my_array = (char**)calloc(allocated, sizeof(char*)); // выделяем предполагаемый минимум if (my_array != NULL) { // программа начинает работать в жесткой реальности for (size_t i = 0; i < real_life_max; i++) { if (i >= allocated) { // принимаем решение увеличивать выделенную память allocated = real_life_max; if ((my_array = realloc(my_array, allocated * sizeof(char*))) == NULL) { printf("realloc error!\n"); exit(-1); } } my_array[i] = (char*)calloc(strlen(sample_str)+1,sizeof(char)); if (my_array[i] == NULL) { printf("calloc-2 error!\n"); exit(-1); } memmove(my_array[i], sample_str, strlen(sample_str)*sizeof(char)); } } else { printf("calloc-1 error!\n"); exit(-1); } // печатаем всю эту шляпу dump(my_array,allocated); // free for (size_t i = 0; i < real_life_max; i++) free(*(my_array+i)); free(my_array); } int main(void) { p2p(); return 0; } Этот код в онлайн исполнении. |
Сообщ.
#3
,
|
|
|
Цитата JoeUser @ if ((my_array = realloc(my_array, allocated * sizeof(char*))) == NULL) { printf("realloc error!\n"); exit(-1); } realloc может вернуть null, при этом старый указатель остаётся валидным и ему нужно сделать free. void p2p() { const char *sample_str = "abc"; const int initial_max = 50; // изначально предполагаем, что этого хватит const int real_life_max = 350; // жизнь показала, что нужно вот столько size_t sz = initial_max; char **my_array = (char**)calloc(sz, sizeof(char *)); // выделяем предполагаемый минимум // программа начинает работать в жесткой реальности for (int i = 0; i < real_life_max; i++) { if (i >= sz) // принимаем решение увеличивать выделенную память { char **tmp = (char**)realloc(my_array, (sz *= 2) * sizeof(char *)); // if (!tmp) break; my_array = tmp; } my_array[i] = (char *)malloc(strlen(sample_str) + 1); strcpy(my_array[i], sample_str); } free(my_array); } |
Сообщ.
#4
,
|
|
|
Цитата Олег М @ при этом старый указатель остаётся валидным и ему нужно сделать free. На будущее учту. Но в этом коде - это лишнее. Ибо идет закрытие проги и ось сама все вернет. Добавлено Олег М, твой free() из 25 строчки не освобождает память, выделенную под сами элементы. |
Сообщ.
#5
,
|
|
|
Всем спасибо, все работает!
|