Skocz do zawartości
kfgz

[Rozw] [C] przenikanie tablic dynamicznych

Rekomendowane odpowiedzi

Jest taki sobie prosty program do obliczania dokładności chodu zegarków mechanicznych

 

#include <stdlib.h>#include <string.h>#include <stdio.h>#include <errno.h>#include <math.h>int FileNotFound(char *path) {    printf("\n\nError while opening file '%s': %s\n\n", path, strerror(errno));    return 1;}int malloc_fail() {        printf("\n\nERROR: Not enougth RAM for allocating buffer\n");    return 1;    }int main(int argc, char *argv[]) {    FILE *inpf;    float atph, t, *arr1, *arr2, *arr3, *tmp, a1_avg = 0, a2_avg = 0, a1_sos = 0, a2_sos = 0, a3_sos = 0;    int x, i, arr2_size, arr1_size = 1;        inpf = fopen(argv[1], "r");    if(inpf == NULL) {        FileNotFound(argv[1]);        exit(1);    }        arr1 = malloc(sizeof(float));    if(arr1 == NULL) {        malloc_fail();        exit(1);    }        while(!feof(inpf)) {        if ((x = fscanf(inpf, "%f", &t)) > 0) {            arr1[arr1_size - 1] = t;            arr1_size++;            tmp = realloc(arr1, sizeof(float)*arr1_size);                if(arr1 != NULL) {                    arr1 = tmp;                } else {                    free(arr1);                    malloc_fail();                    exit(1);                  }        } else if(x == 0) break;    }            fclose(inpf);        arr1_size--;    arr2_size = arr1_size - 1;        if (arr2_size <= 0) {        printf("\nNot enough data!\n\n");        exit(1);    }        arr2 = malloc(sizeof(float)*arr2_size);    if(arr2 == NULL) {        malloc_fail();        exit(1);    }        arr3 = malloc(sizeof(float)*arr2_size);    if(arr3 == NULL) {        malloc_fail();        exit(1);    }        for(i = 0; i < arr2_size; i++)        arr2[i] = arr1[i + 1] - arr1[i];        /*a1_avg*/    for(i = 0; i < arr1_size; i++)        a1_avg += arr1[i];    a1_avg /= arr1_size;        /*a2_avg*/    for(i = 0; i < arr2_size; i++)        a2_avg += arr2[i];    a2_avg /= arr2_size;        /*a1_sos*/    for(i = 0; i < arr1_size; i++)        a1_sos += (arr1[i] - a1_avg) * (arr1[i] - a1_avg);    a1_sos = sqrtf(a1_sos) / arr1_size;        /*a2_sos*/    for(i = 0; i < arr2_size; i++)        a2_sos += (arr2[i] - a2_avg) * (arr2[i] - a2_avg);    a2_sos = sqrtf(a2_sos) / arr2_size;        /*tph*/    atph = (3600.0 + a2_avg / 24.0) * 5.0;    for(i = 0; i < arr2_size; i++)        arr3[i] = (3600.0 + arr2[i] / 24.0) * 5.0;    for(i = 0; i < arr2_size; i++)        a3_sos += (arr3[i] - atph) * (arr3[i] - atph);    a3_sos = sqrtf(a3_sos) / arr2_size;        free(arr1);    free(arr2);    free(arr3);    printf("Avg ticks per hour = %.2f +/- %.3f\n", atph, a3_sos);    printf("Avg daily drift = %.1f +/- %.2f\n", a2_avg, a2_sos);    printf("Avg absoulte drift = %.1f +/- %.2f\n\n", a1_avg, a1_sos);    printf("Number of good samples: %d\n\n", arr1_size);        return 0;}

Wszystko byłoby pięknie gdyby nie to, że po wykonaniu pętli for po linii // ******** // zmienia się wartość ostatniej komórki tablicy arr2 (tj. arr2[arr2_size - 1] = arr3[0]). Gdy usunę komentarz sprzed linii

 

//arr2[arr2_size - 1] = arr1[arr2_size] - arr1[arr2_size - 1];

to arr2 jest już w porządku ale z kolei wtedy arr3[0] = arr2[arr2_size - 1] o_O. Spotkał się ktoś kiedyś z takim "voodoo"?

 

Dane dla programu są w pliku w postaci liczbowej (różnica w czasie w sekundach) np

 

-31-32-27-14-14-6-3-73-3

Wywołanie programu

 

progs plik_z_danymi.txt
Edytowane przez kfgz

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ostatnia linijke w C napisalem pewnie jakies 5 lat temu, ale imho:

a)inicjalizujesz wskazniki arr2, arr3 poprzez malloc(jakis_tam_size), a powinno byc jakis_tam_size*size_elementu

b)nie jestem pewien ale to wyrazenie w problematycznej linijce // ******** // moze miec typ double a nie float, chociaz wtedy powinien krzyknac cos kompilator.

c)ostatnia komorka tablicy arr2 to bedzie arr2[arr2_size -1] a nie arr2[arr2_size] - napisales (tj. arr2[arr2_size] = arr3[0]) a to akurat najprawdopodobniej jest prawda bo kompilator raczej zaalokuje te tablice/wskazniki jeden po drugim - czyli nastepny adres po ostatnim adresie nalezacym do arr2 bedzie pierwsza komorka arr3 :)

  • Upvote 1

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ad. 1 To może być to. Zaraz sprawdzę.

 

Ad. 2. Nie sądzę. Wszystkie obliczenia są na float.

 

Ad. 3. Literówka ;) Już poprawiłem.

 

 

EDIT:

 

Jednak to był mój czeski błąd. Dzięki za pierwszą wskazówkę. Kod poprawiłem w poście. W sumie to powinienem się domyśleć po użyciu realloc. No cóż... widocznie miałem dziś małe zaćmienie.

Edytowane przez kfgz

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Gość <account_deleted>

Może jestem zaspany ale z tego co widzę to:

arr1_size = 1;

czyli: arr1 = (float*) malloc(1) -> jakoś nie widzę szansy zmieścić float'a w 1 bajcie ;)

jeśli już to powinno być:

arr1 = (float*) malloc( size_of(float) * arr1_size );

...itd arr2, arr3

 

defakto operujesz poza zaalokowanymi obszarami -> mess.

 

edit: jestem zaspany -> Quad już to napisał...

Edytowane przez tomazzi

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...