Problem ze strykturą i zwalnianiem pamieci

Problem ze strykturą i zwalnianiem pamieci
sobek343s22
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:4
0

cześć mam problem z nieobsługiwanym wyjątkiem. MV zgłasza mi "Zgłoszono nieobsługiwany wyjątek: naruszenie dostępu do odczytu.
WW2 było nullptr."" po wywołaniu funkcji czysc ale tylko gdy stos jest pusty .Proszę o pomoc

Kopiuj
void *MY_STUDENT_MALLOC(char *nnazwisko, size_t size_nnazwisko, size_t rok, KIERUNEK kierunek)
{
	MY_STUDENT *WW1 = (MY_STUDENT *)malloc(sizeof(MY_STUDENT));

	if (WW1)
	{
		WW1->nazwisko = (char *)malloc(size_nnazwisko * sizeof(char));
		if (!(WW1->nazwisko))
			printf("error // MY_STUDENT_MALLOC2");
		memcpy(WW1->nazwisko, nnazwisko, size_nnazwisko);
		WW1->size_nazwisko = size_nnazwisko;
		WW1->rok = rok;
		WW1->kierunek = kierunek;
	}
	else printf("error // MY_STUDENT_MALLOC2 ");
	return (void *)(WW1);
}

Kopiuj
void MY_STUDENT_CZYSC(void *wsk)
{
	
	MY_STUDENT *WW2 = (MY_STUDENT *)wsk;
	
	
	if (WW2->nazwisko) {                 // Tu zgłasza wyjątek
		free((WW2)->nazwisko);
		
		
	}
	if (WW2 == NULL) {
		printf("Pusto1");
	}
	else if (WW2) {
		free(WW2);
	}

	}

Kopiuj
struct MY_STUDENT
{
	enum KIERUNEK kierunek;
	char *nazwisko;
	size_t size_nazwisko;
	size_t rok;
};

AK
Oczywiście że gdy wskaźnik jest NULL, użycie tego co on wskazuje da na współczesnych systemach wyjątek. Rozumiem, że to wiesz.
AK
Styl tego jest taki sobie, np za dużo void*
cerrato
Czy tylko ja tak mam, że czytając "stryktura" w głowie słyszę głos żandarna z "Allo Allo" i jego słynne "dziń dybry" :D
au7h
y jest obok u na klawiaturze, jak ktoś ma grube lub tłuste palce łatwo się pomylić :P
MarekR22
FYI w C castowanie pomiędzy void * a dowolnym innym wskaźnikiem jest robione domyślnie. Nie trzeba nic pisać. To w C++ trzeba castować z void* do innego wskaźnika.
lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 3 godziny
  • Postów:4944
0

Słusznie piszą w komentarzach, można to uprościć bez tych "voidów", przykładowa struktura:

Kopiuj
typedef struct {
	int val;
}Example;

Example * exampleInit() {
	 Example * obj = (Example * ) malloc(sizeof(Example));
	if (obj == NULL) {
		fprintf(stderr, "%s", "Example, constructor: Malloc failed!\n");
		abort();
	}
return obj;
}

void clear(Example ** ptr) {
	free(*ptr);
	*ptr = NULL;
}

sobek343s22
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:4
0

Tylko program niestety musi mieć te "voidy" jest to zarzucone z góry , a da się jakoś ominąć ten wyjątek jeśli wskaźnik jest na NULL?

twonek
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
0
Kopiuj
if (WW2 == NULL)
{
    printf("Pusto1");
}
else
{
    if (WW2->nazwisko)
    { 
        free((WW2)->nazwisko);
    }
    free(WW2);
}
edytowany 1x, ostatnio: twonek
lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 3 godziny
  • Postów:4944
0
sobek343s22 napisał(a):

Tylko program niestety musi mieć te "voidy" jest to zarzucone z góry , a da się jakoś ominąć ten wyjątek jeśli wskaźnik jest na NULL?

To na upartego można, Dodaj tylko sprawdzenie NULLA:

Kopiuj
void * exampleInit(int elem) {
	 Example * obj = (Example * ) malloc(sizeof(Example));
	if (obj == NULL) {
		fprintf(stderr, "%s", "Example, constructor: Malloc failed!\n");
		abort();
	}
	obj->val = elem;
	return (void *)obj;
}


void clear2(void ** ptr) {
	if (ptr) {
		// uwolnienie innych zasobów wskazywanych przez ptr;
		free(*ptr);
		*ptr = NULL;
	}
	else 
		puts("Null pointer"); // albo stderr
}

MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:23 minuty
0
Kopiuj
struct MyStudent
{
    enum KIERUNEK kierunek;
    char *nazwisko;
    size_t rok;
};
typedef struct MyStudent *MyStudentRef;

MyStudentRef MyStudentCreate(const char *nazwisko, size_t rok, KIERUNEK kierunek)
{
     MyStudentRef r = malloc(sizeof(struct MyStudent));
     if (r) {
          r->nazwisko = strdup(nazwisko);
          r->rok = rok;
          r->kierunek = kierunek;
     }
     return r;
}

void MyStudentFree(MyStudentRef student)
{
     if (!student) return;
     free(student->nazwisko);
     free(student);
}

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
Zobacz pozostały 1 komentarz
MarekR22
To tylko kwestia "coding convention". Np tak to wygląda na Mac OS i chyba też BSD. To że przez pomyłkę wstawiłem . niczego nie dowodzi. Kompilator by mnie naprostował.
BG
Oczywiście że poprawi. Tylko na potrzeby początkującego pytającego - popraw jeszcze malloca (albo dodaj jeszcze jednego typedef-a) - bo albo MyStudent nie jest typem, albo musisz zrzutować wynik malloc-a do MyStudentRef ;)
MarekR22
w C rzutowanie z void* jest zbędne (kompilator robi to sam).
BG
Oczywiście - ja to wiem, Wy to wiecie. Chodziło mi o konstrukcję MyStudentRef r = malloc(sizeof(MyStudent)); Albo piszemy w C i wtedy musi być sizeof(struct MyStudent), albo piszemy w "C" i kompilujemy to jako C++ - ale wtedy trzeba wynik malloc-a zrzutować.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.