#c #динамические_массивы
Доброго времени суток. Есть такая задача. Вводится строка, программа должна разбить ее на лексемы, сохранить их в массив data, выполнить какие-то операции и потом успешно завершится. С алгоритмом проблем нет, но вот очистка памяти не работает. Если что, точно известно: количество слов точно не может быть более 25, длина слова - не более 20 символов. int main() { char* string = (char*)malloc(sizeof(char) * 500); fgets(string, 500, stdin); char** data = (char**)malloc(sizeof(char*) * 25); for (int i = 0; i < 25; i++) { data[i] = (char*)malloc(sizeof(char) * 20); } int length = 0; data[length] = strtok(string, " "); length++; while (data[length - 1] != NULL) { data[length] = strtok(NULL, " "); length++; } //Do Something for (int i = 0; i < length; i++) { free(data[i]); } free(data); free(string); return 0; }
Ответы
Ответ 1
Как только вы делаете вот этот финт: data[length] = т.е. присваиваете указателю новое значение, старое, указывающее на выделенную память, теряется. Получается утечка памяти. А затем вы пытаетесь удалять то, что не выделяли. Или просто используйте массив указателей, или, если выделяете память для хранения слов - копируйте слова в выделенную память. Update Вариант 1: int main() { ... char** data = (char**)malloc(sizeof(char*) * 25); for (int i = 0; i < 25; i++) data[i] = NULL; int length = 0; for(char * с = strtok(string, " ");c;c = strtok(NULL, " ")) { data[length++] = c; } //Do Something free(data); free(string); } Вариант 2: int main() { ... char** data = (char**)malloc(sizeof(char*) * 25); for (int i = 0; i < 25; i++) data[i] = (char*)malloc(sizeof(char) * 20); int length = 0; for(char * с = strtok(string, " ");c;c = strtok(NULL, " ")) { strcpy(data[length++],c); } //Do Something for (int i = 0; i < 25; i++) { free(data[i]); } free(data); free(string); } Я бы все же добавил проверки на количество слов и длину... Мало ли кто что обещает...Ответ 2
Для копирования выдаваемого strtok() слова в динамическую память проще всего использовать функцию strdup #ifndef _GNU_SOURCE #define _GNU_SOURCE // for getline() with gcc -std=c11, c99 etc... #endif #include#include #include char ** get_25words (char *s, size_t *nw) { char **w = (__typeof__(w))malloc(sizeof(char *) * 25); // type cast for c++ for (*nw = 0; *nw < 25; (*nw)++, s = 0) { char *t = strtok(s, " "); if (t) w[*nw] = strdup(t); else break; } return w; } int main (int ac, char *av[]) { char *s = 0; size_t sz; while (getline(&s, &sz, stdin) > 0) { size_t nw; char **w = get_25words(s, &nw); printf("found %zu words\n", nw); for (size_t i = 0; i < nw; i++) { printf("%s\n", w[i]); free(w[i]); } free(w); } free(s); } А читать строки неопределенной длины очень удобно функцией getline
Комментариев нет:
Отправить комментарий