• 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.

VPS Starter Arubacloud
0 głosów
346 wizyt
pytanie zadane 24 stycznia 2023 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 28 stycznia 2023 przez Oscar Nałogowiec (29,210 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ź 24 stycznia 2023 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 24 stycznia 2023 przez TOWaD Mądrala (5,540 p.)
to c++ że (char*)malloc(sizeof(char)*length) a nie malloc(sizeof(char)*length
komentarz 25 stycznia 2023 przez mokrowski Mędrzec (155,460 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 28 stycznia 2023 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 28 stycznia 2023 przez TOWaD Mądrala (5,540 p.)
edycja 28 stycznia 2023 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 28 stycznia 2023 przez mokrowski Mędrzec (155,460 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ź 372 wizyt
0 głosów
1 odpowiedź 121 wizyt
pytanie zadane 15 czerwca 2018 w C i C++ przez kietek Początkujący (280 p.)
0 głosów
1 odpowiedź 282 wizyt

92,305 zapytań

141,109 odpowiedzi

318,585 komentarzy

61,756 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...