Программа валится при освобождении памяти под динамический массив - C (СИ)
Формулировка задачи:
Доброго времени суток. Проблема такая. Моя программа представляет собой поразрядную сортировку даты вида dd.mm.yyyy, пока я тестирую только по году. В функции radix_mas разряды года проверяются справа налево. Есть массив векторов под каждую цифру. Когда все элементы были раскиданы по данному разряду, вектора удаляются и затем создаются снова для следующего разряда. Если все даты на данном разряде имеют разные цифры, то есть каждый вектор состоит максимум из одного элемента, то все нормально. Если же под данную цифру попадает 2 или больше дат, то realloc-ом увеличиваю размер на 1 элемент и помещаю очередную дату. А вот после того, как на получился новый массив дат из всех этих векторов (в программе я это делаю справа налево из-за особенности функции pop_list), мне нужно удалить эти вектора функцией destroy. И вот здесь, когда более одного элемента в векторе, начинаются проблемы - программа падает. Подскажите пожалуйста, что исправить?
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> typedef struct data data; struct data { int day; int month; int year; }; typedef struct pair pair; struct pair { char inf[64]; data key; }; typedef struct slist slist; struct slist { //реализация вектора на массиве int size; pair *data; }; void create(slist* l) { l->data = malloc(sizeof(pair)); l->size = 0; } void push_list(slist* l, pair a) { printf("36\n"); if (l->size!=0) realloc(l,sizeof(pair)*(l->size+1)); printf("38\n"); l->data[l->size]=a; printf("40\n"); int i=l->size; printf("l.size = %d\n", l->size); while (i>=0) { printf("l[%d]: info = %s, key = %d.%d.%d\n", i, l->data[i].inf, l->data[i].key.day, l->data[i].key.month, l->data[i].key.year); i--; } l->size++; } bool isEmpty (slist* l) { return (l->size==0); } pair pop_list(slist* l) { l->size--; return (l->data[l->size]); } void destroy(slist* l) { l->size=0; free(l->data); } void radix_mas(pair a[], int n, const int t1, const int t2)//t1 - кол-во разрядов в году { printf("59\n"); //t2 - кол-во разрядов в месяце и дне int i,j,k,d,m=1; struct slist s[10]; //сортировка по году for (j=1; j<t1; j++) { for (i=0; i<10; i++) create(&s[i]); for (i=0; i<n; i++) printf("s[%d]: info = %s, key = %d.%d.%d\n", i, a[i].inf, a[i].key.day, a[i].key.month, a[i].key.year); printf("64\n"); for (k=0; k<n; k++) { printf("inf = %s key = %d.%d.%d\n", a[k].inf, a[k].key.day, a[k].key.month, a[k].key.year); d =((int)(a[k].key.year/m))%(int)10; printf("d = %d\n", d); printf("67\n"); printf("k = %d\n", k); push_list(&s[d], a[k]); printf("76_\n"); } //int z=0; /*for (i=0; i<=9; i++) { printf("size[i] = %d\n", s[i].size); while (s[i].size-z>0) { printf(" i = %d, year = %d\n", i, s[i].data[s[i].size-z-1].key.year); z++; } }*/ i=9; printf("79\n"); for (k=n-1; k>=0; k--) { printf("81\n"); if (!isEmpty(&s[i]) && i>=0) { printf("83\n"); a[k]=pop_list(&s[i]); printf("83_\n");} else { printf("86\n"); while (isEmpty(&s[i]) && i>=0) i--; printf("i= %d\n", i); if (i<0) break; else { printf("90\n"); a[k]=pop_list(&s[i]); printf("k = %d\n", k); } } } for (i=0; i<10; i++) printf("93 | i =%d, size = %d\n", i, s[i].size); for (i=0; i<10; i++) if (isEmpty(&s[i])) {printf("94 | i =%d, size = %d\n", i, s[i].size); destroy(&s[i]);} else printf("error %d\n", i); m=m*10; printf("m = %d\n", m); } /*//сортировка по месяцу for (j=1; j<t2; j++) { for (k=0; k<n; k++) { d =((int)(a[k].key.month/m))%(int)10; if (s[d].data==NULL) { create(&s[d]); push_list(&s[d],a[k]); } else push_list(&s[d], a[k]); } i=9; for (k=n-1; k>=0; k--) { if (!isEmpty(&s[i]) && i>=0) a[k]=pop_list(&s[i]); //из-за изъятия элемента из конца вектора считывание элементов векторов начинается с конца else { while (isEmpty(&s[i]) && i>=0) i--; if (i<0) break; else a[k]=pop_list(&s[i]); } } for (i=0; i<10; i++) if (isEmpty(&s[i])) destroy(&s[i]); m=m*10; } //сортировка по дню for (j=1; j<t2; j++) { for (k=0; k<n; k++) { d =((int)(a[k].key.day/m))%(int)10; if (s[d].data==NULL) { create(&s[d]); push_list(&s[d],a[k]); } else push_list(&s[d], a[k]); } i=9; for (k=n-1; k>=0; k--) { if (!isEmpty(&s[i]) && i>=0) a[k]=pop_list(&s[i]); else { while (isEmpty(&s[i]) && i>=0) i--; if (i<0) break; else a[k]=pop_list(&s[i]); } } for (i=0; i<10; i++) if (isEmpty(&s[i])) destroy(&s[i]); m=m*10; }*/ } int main(void) { char tmp[16]; const int n = 5; //количество дат pair d[n]; char mystring[60]; int j; printf("enter key dd.mm.yyyy and string after tabulation\n"); for (j = 0; j < n; j++) { gets(mystring); printf("===%s===\n",mystring); char* pch = strtok (mystring,"\t"); int i=0; int k=0; while (pch != '\0') //разделение строки на ключ и информацию { switch(i) { case 0: strcpy(tmp,pch); break; default: strcpy(d[j].inf,pch); break; } pch = strtok (NULL, "\t"); i++; } char* pt = strtok(tmp, "."); while (pt != NULL) { switch(k) //разделение ключа { case 0: d[j].key.day = atoi(pt); break; case 1: d[j].key.month = atoi(pt); break; case 2: d[j].key.year = atoi(pt); break; } pt = strtok (NULL, "."); k++; } //mystring[0] = '\0'; //gets(mystring); } printf("!!!!!!!\n"); int s; for (s=0; s<n; s++) printf("inf = %s key = %d.%d.%d\n", d[s].inf, d[s].key.day, d[s].key.month, d[s].key.year); //} radix_mas(d, n, 4, 2); int i; for (i=0; i<n; i++) printf("%d.%d.%d \t %s\n", d[i].key.day, d[i].key.month, d[i].key.year, d[i].inf); return 0; }
Решение задачи: «Программа валится при освобождении памяти под динамический массив»
textual
Листинг программы
if( s[i].data!=NULL) destroy(&s[i]);
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д