W zadaniu mam za zadanie odczytać dane z pliku, a następnie zrobić na tych danych obliczenia statystyczne i wpisać je do struktury. Cały program działa poprawnie, az do momentu, kiedy mam wyświetlić dane ze struktury w ostatnich linijkach kodu:
struct statistic_t** p=NULL;
rval = statistics_row(D, p);
if (rval == 1 || rval == 2) {
destroy(&D);
printf("Failed to allocate memory");
return 8;
}
for (i = 0; i < rval; i++) {
printf("%d %d %d\n", (*(p+i))->min, (*(p + i))->max, (*(p + i))->range));
free(*(p + i));
}
gdzie program wywala błąd, ze próbuje wyłuskać NULL podczas printf'a.. W funkcji "statistics_row" dokładnie tak samo odwołuję się do elementów struktury np.:
(*(stats + i))->max = max;
i w tym przypadku, mimo moim zdaniem odwolania sie do tego samego miejsca w pamięci wszystko gra. Dodatkowo w funkcji wskaznik typu "statistic_t" jest przekazany na takim samym poziomie zagniezdzenia tylko zamiast "p" jest "stats" :
int statistics_row(int** ptr, struct statistic_t** stats) {
jak jest zadeklarowany w funkcji main():
struct statistic_t** p=NULL;
, więc nie widzę zadnej roznicy pomiędzy jednym a drugim uzyciem. Oto mój kod:
struct statistic_t
{
int min;
int max;
float avg;
float standard_deviation;
int range;
};
int statistics_row(int** ptr, struct statistic_t** stats) {
if (ptr == NULL || (*(ptr + 0) + 0) == NULL) {
return 1;
}
int h = 0, w=0;
while (*(ptr + h) !=NULL) {
if (*(*(ptr + h) + w) == -1) {
h++;
w = 0;
}
w++;
}
stats= (struct statistic_t**)malloc(h*sizeof(struct statistic_t*));
if (stats == NULL) {
return 2;
}
int i = 0, q = 0;
for ( i = 0; *(ptr + i) != NULL; i++, q++) {
int max = *(*(ptr + i) + 0), min = *(*(ptr + i) + 0), counter = 0, flag = 0;
float sum = 0, temp = 0;
for (int x = 0;; x++) {
if (*(*(ptr + i) + x) == -1) {
if (x == 0) {
flag++;
}
break;
}
if (min > * (*(ptr + i) + x)) {
min = *(*(ptr + i) + x);
}
if (max < *(*(ptr + i) + x)) {
max = *(*(ptr + i) + x);
}
sum += *(*(ptr + i) + x);
counter++;
}
*(stats + i) = (struct statistic_t*)malloc(sizeof(struct statistic_t));
if (*(stats + i) == NULL) {
for (int k = 0; k < i; k++) {
free(*(stats + i));
free(stats);
}
return 2;
}
if (flag == 1) {
(*(stats + i))->min = -1;
(*(stats + i))->max = -1;
(*(stats + i))->avg = -1;
(*(stats + i))->range = -1;
(*(stats + i))->standard_deviation = -1;
}
else {
(*(stats + i))->min = min;
(*(stats + i))->max = max;
(*(stats + i))->avg = (float)sum / counter;
(*(stats + i))->range = max - min;
sum = 0;
for (int i2 = 0; *(ptr + i2) != NULL; i2++) {
for (int x2 = 0; *(*(ptr + i2) + x2) != -1; x2++) {
sum = powf((*(*(ptr + i2) + x2) - (*stats)->avg), 2);
temp += sum / counter;
}
}
(*(stats + i))->standard_deviation = sqrtf(temp);
}
}
return i;
}
int main() {
int** D;
enum save_format_t format;
char* filename = (char*)malloc(40);
if (filename == NULL) {
printf("Failed to allocate memory");
return 8;
}
printf("Enter filename: ");
char f;
int i = 0;
while (1) {
if (scanf("%c", &f) == 0) {
printf("Incorrect input");
return 1;
}
else {
if (f == '\n') {
break;
}
if (i > 38) {
}
else {
*(filename + i) = f;
i++;
}
}
}
*(filename + 39) = '\0';
*(filename + i) = '\0';
char* ptr = filename;
while (*(ptr + 4) != '\0') {
ptr++; i++;
}
if ((strcmp(ptr, ".txt") != 0 || i == 0)){
if (strcmp(ptr, ".bin") != 0 && i == 0) {
printf("Unsupported file format");
return 7;
}
else {
format = 1;
}
}
else {
format = 0;
}
i = 0;
if (filename == NULL) {
printf("Failed to allocate memory");
return 8;
}
int rval = 0;
rval = load(filename, &D, format);
if (rval == 2) {
printf("Couldn't open file");
free(filename);
return 4;
}
if (rval == 3) {
printf("File corrupted");
free(filename);
return 4;
}
if (rval == 4) {
printf("Failed to allocate memory");
free(filename);
return 4;
}
free(filename);
struct statistic_t** p=NULL;
rval = statistics_row(D, p);
if (rval == 1 || rval == 2) {
destroy(&D);
printf("Failed to allocate memory");
return 8;
}
for (i = 0; i < rval; i++) {
printf("%d %d %d\n", (*(p+i))->min, (*(p + i))->max, (*(p + i))->range));
free(*(p + i));
}
free(p);
p = NULL;
destroy(&D);
return 0;
}