как всегда, есть код (приведен ниже).
при запуске программы вылетает:
*** glibc detected *** malloc(): memory corruption (fast): 0x0804f070 ***
Aborted
что должна делает программа: в функцию char ** get_elements() передается строка "3, 4, 5, 6". эта функция должна создать char **, раскидав в каждый char * строки: "3", " 4", " 5", " 6".
т.е.
char ** rrr = NULL;
rrr = get_elements("3, 4, 5, 6");
после должно быть так:
rrr[0] = "3";
rrr[1] = " 4";
rrr[2] = " 5";
rrr[3] = " 6";
rrr[4] = NULL;
вся суть в функции get_elements() - вот только где там ошибка я так и не понял.
подскажите, плиз.
ЗЫ: функции add_char_to_string() и safe_free() никогда не подводили.
void safe_free(char ** str)
{
if (!(*str))
return;
free(*str);
*str = NULL;
};
char * add_char_to_string(char * str, char byte)
{
char * result = NULL;
unsigned int len = 0;
if (!str)
len = 0;
else
len = strlen(str);
result = (char*) calloc(len+2, sizeof(char));
if (!result)
return NULL;
if (len != 0)
strcat(result,str);
result[len] = byte;
result[len+1] = '\0';
if (str)
safe_free(&str);
return result;
};
char ** get_elements(char * params)
{
char ** result = NULL;
unsigned int len = 0, i = 0, k = 0;
char * temp = NULL;
if (!params)
return NULL;
if (strlen(params) == 0)
return NULL;
len = strlen(params);
while (1) {
for(; i < len; i++) {
if (params[i] == ',')
break;
temp = add_char_to_string(temp, params[i]);
}
k++;
i++;
if (!result)
result = (char **) calloc(k + 1, sizeof(char *));
else
result = (char**) realloc(result, k + 1);
result[k] = 0;
result[k-1] = temp;
if (i >= len) {
break;
}
temp = NULL;
}
return result;
}
int main(int argc, char *argv[])
{
char ** rrr = NULL;
rrr = get_elements("3, 4, 5, 6");
if (!rrr) {
printf("Wrong\n");
}
else {
printf("Not bad\n");
}
return EXIT_SUCCESS;
};
я изменил блок:
if (!result)
result = (char **) calloc(k + 1, sizeof(char *));
else
result = (char**) realloc(result, k + 1);
на:
if (!result)
result = (char **) calloc(k + 1, sizeof(char *));
else {
result_tmp = (char **) calloc(k + 1, sizeof(char *));
for (c = 0; c < k; c++)
result_tmp[c] = result[c];
result = result_tmp;
}
result_tmp имеет тип char **.
т.е., верно ли то, что realloc() неверно делал свое дело ?
в мане к нему нет подсказок насчет этого ?
> верно ли то, что realloc() неверно делал свое дело ?
Да, но поправить это можно было намного проще:
- result = (char**) realloc(result, k + 1);
+ result = (char**) realloc(result, (k + 1)*sizeof(char*));
Вообще, если посмотреть, то calloc у тебя везде лишний, в том смысле, что выполняет лишнюю работу по инициализации памяти нулями. Используй malloc. В add_char_to_string замени strcat на strcpy.
Хотя, один фиг, это слабо все поможет :) Дерьмовый код, надо сказать.
Эффективность ниже плинтуса. Очень много выделений памяти. Если эффективность не нужна, то зачем тогда C и весь этот геморрой? На Python это пишется в 1 строку:
а потому что если его переписать с помощью strtok и str(n)cpy, то он будет в 10 раз короче и понятнее :) А если еще посчитать количество "," заранее, то и от realloc можно избавиться.
> роще создать функцию что-то типа params_free(char **), и в мануале написать что для освобождения памяти надо использовать ее.
Тогда надо дополнительно еще что-то изобретать. Ибо, кто мне помешает переколбасить порядок элементов в массиве (отсортировать, например)? В общем, по любому, геморрой.
Любой дополнительный сервис понижает быстродействие :)
Если надо переколбасить строку в 10 метров, то это самое то.
Ну а по большому счету при современных мощностях овчинка выделки не стоит. Хотя не зря ведь JavaVM откусывает 30-40 метров памяти, после чего сама себе там что-то творит.