• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wpisanie do struktury dane z pliku w C.

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
0 głosów
63 wizyt
pytanie zadane 4 dni temu w C i C++ przez k0n6710r Nowicjusz (160 p.)

Witam, mam delikatny problem, który jest związany wpisaniem danych do struktury z pliku. W konsoli pojawia się błąd 0xC0000005 przy wywołaniu funkcji "readEventsFromFile" czyli próbuje uzyskać dostęp do pamięci gdzie nie mam dostępu. Może ktoś szybko spojrzeć i wskazać problem w moim kodzie?
 

int Size = getCount("events.txt");
Event* event = createEventArray(Size);

for(int i=0; i<Size; i++)
    initEventVariables(event, LENGTH);

readEventsFromFile(event, Size);

W taki sposób tworzę strukture Event i rezerwuje pamięć dla zmiennych w strukturze:
 

Event* createEventArray(int Size){
    Event* event = (Event*)malloc(sizeof(Event)*Size);
    return event;
}

void initEventVariables(Event* event, int length){
    event->home = (char*)malloc(sizeof(char)*length);
    event->away = (char*)malloc(sizeof(char)*length);
    event->date = (char*)malloc(sizeof(char)*length);
    event->time = (char*)malloc(sizeof(char)*length);
}

I tutaj mam problem ze skanowaniem pliku i zapisaniem zmiennych do struktury:

void readEventsFromFile(Event* event, int Size){
    FILE* file = fopen(fileName, "r");
    for(int i=0; i<Size; i++) //Następna linia prawdopodobnie błąd
        fscanf(file, "%d %s %s %s %s", &event[i].type, event[i].home, event[i].away, event[i].date, event[i].time);
    fclose(file);
}


 

komentarz 20 godziny temu przez Oscar Nałogowiec (27,850 p.)

Wracając do originalnego kodu, w linii 5 w pierwszym kodzie nie indeksowałeś tablicy, inicjowałeś zawsze 1.  element, czyli ciągle allokowałeś do tych samych zmiennych => wyciek pamięci. Powinno być:

for(int i=0; i<Size; i++)
    initEventVariables(event+i, LENGTH); // lub &event[i]

 

1 odpowiedź

0 głosów
odpowiedź 4 dni temu przez k0n6710r Nowicjusz (160 p.)

Dobra wsadziłem funkcje initEventVariables do createEventArray w taki sposób i działa:
 

Event* createEventArray(int Size, int length){
    Event* event = (Event*)malloc(sizeof(Event)*Size);
    for(int i=0; i<Size; i++){
        event[i].home = (char*)malloc(sizeof(char)*length);
        event[i].away = (char*)malloc(sizeof(char)*length);
        event[i].date = (char*)malloc(sizeof(char)*length);
        event[i].Time = (char*)malloc(sizeof(char)*length);
    }
    return event;
}

 

komentarz 4 dni temu przez TOWaD Gaduła (3,770 p.)
to c++ że (char*)malloc(sizeof(char)*length) a nie malloc(sizeof(char)*length
komentarz 4 dni temu przez mokrowski Mędrzec (153,580 p.)

@k0n6710r,

Kilka pytań na które warto sobie odpowiedzieć:

  1. Czy wiesz że w języku C, malloc(...) zwraca void *?
  2. Co zrobisz jeśli nie powiedzie się rezerwacja pamięci w którymkolwiek 5 przypadków?
  3. Czy wiesz jak wygląda pamięć alokowana na taką tablicę struktur po wykonanej w ten sposób alokacji?
  4. Jak wykonujesz zwolnienie pamięci tak alokowanej?
komentarz 23 godziny temu przez k0n6710r Nowicjusz (160 p.)

Nie mam pojęcia jak i w jaki sposób rezerwuje pamięć dla tablicy struktur, ale robię w taki sposób zamiast na zwykłych tablicach bo ode mnie wymagano. Tak nie udostępniłem zwalniania pamięci ale zwalniam ją w taki sposób:
 

void freeEvent(Event* event, int Size){
    for(int i=0; i<Size;i++) {
        free(event[i].home);
        free(event[i].away);
        free(event[i].date);
        free(event[i].Time);
    }
    free(event);
}

 

komentarz 22 godziny temu przez TOWaD Gaduła (3,770 p.)
edycja 22 godziny temu przez TOWaD

Zwalnianie wygląda oki. Ale wszystkie data i czas maja taką samą długość?

edit: Oczywiście poza przypadkiem jaki:

Co zrobisz jeśli nie powiedzie się rezerwacja pamięci w którymkolwiek 5 przypadków?

W danej iteracji możesz zwolnić tylko to co zarezerwowałeś. i tylko do tej iteracji.

komentarz 20 godziny temu przez mokrowski Mędrzec (153,580 p.)
bool createEventFields(struct Event * event, int length) {

	event->home = malloc(sizeof(*(event->home)) * length);
	if (event->home == NULL)
		goto exit_1;

	event->away = malloc(sizeof(*(event->away)) * length);
	if (event->away == NULL)
		goto exit_2;

	event->date = malloc(sizeof(*(event->date)) * length);
	if (event->date == NULL)
		goto exit_3;

	event->Time = malloc(sizeof(*(event->Time)) * length);
	if (event->Time == NULL)
		goto exit_4;

	return true;

exit_4:
	free(event->Time);
exit_3:
	free(event->date);
exit_2:
	free(event->away);
exit_1:
	free(event->home);

	return false;
}

void deleteEventFields(struct Event * event) {
	free(event->home);
	free(event->away);
	free(event->date);
	free(event->Time);
}

struct Event * createEventsArray(int size, int length){
    struct Event * events = malloc(sizeof(struct Event) * size);
    if (events == NULL) 
    	    goto exit_0;

    int i = 0;
    for(; i < size; ++i){
    	if (! createEventFields(&(events[i]), length))
    		goto exit_1;
    }
    return events;

exit_1:
    while (i--) {
    	    deleteEventFields(&(events[i]));
    }

exit_0:
    free(events);

    return NULL;
}

void deleteEventsArray(struct Event * events, int size) {
	while(size--) {
		deleteEventFields(&(events[size]));
	}
	free(events);
}

 

Podobne pytania

0 głosów
1 odpowiedź 326 wizyt
0 głosów
1 odpowiedź 101 wizyt
pytanie zadane 15 czerwca 2018 w C i C++ przez kietek Początkujący (280 p.)
0 głosów
1 odpowiedź 148 wizyt

90,310 zapytań

138,910 odpowiedzi

311,123 komentarzy

60,024 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...