Naruszenie ochrony pamięci, przy operowaniu na tablicy dwuwymiarowej

0

Mam problem z następującym kodem, cały czas wywala mi błąd: Naruszenie ochrony pamięci:

int ilosc_testow;
fscanf("%i",&ilosc_testow);
int max = 128;
int size = 3*ilosc_testow;
int j;
char** dane = (char**)malloc(size*sizeof(char*));
for(j=0;j<size;j++){
    dane[j] = (char*)malloc(max*sizeof(char));
}

int i;
i = 0;
while(fscanf(f,"%s",&dane[i]) != EOF){
    printf("%s",dane[i]);
    i++;
}

Tablica ta jest zwalniana później. Wszystko działa dla ręcznie utworzonej tablicy np. char napisy[10][20], jednakże tutaj coś nie gra. Domyślam się, że błąd "Naruszenie ochrony pamięci" dotyczy min. niepoprawnego odnoszenia się do zmiennych, gdzie to pewnie ma miejsce w pętli while. Jednakże przy tej ręcznie utworzonej tablicy mogłem spokojnie odwoływać się w pętli while w taki sposób dane[i] a jest ona również tablicą dwuwymiarową. Jakieś pomysły ? Niestety jestem laikiem w programowaniu.

0

&dane[i]
W ten sposób pobierasz adres wskaźnika. Powinno być samo dane[i], tam przecież wrzuciłeś wynik malloc'a.
Tak jak ze zmienną:

char *str = (char*)malloc(...
scanf("%s", str);

Zrób też z komórką tablicy:

dane[j] = (char*)malloc(...
fscanf(f, "%s", dane[i]);

I jeszcze powinieneś powiedzieć funkcji fscanf jaki rozmiar ma bufor żeby nie doszło do przykrej niespodzianki jak w pliku będzie dłuższy łańcuch.
Bufor ma 128 znaków więc daj taki format:

"%127s"
0

Wielkie dzięki adf88. Wszystko działa już jak należy :)

0

Mam jeszcze podobny problem z tym kodem, wypisuje on same 0 (gdzie powinny pojawiać się jakieś inne wartości - liczby całkowite):

for(i=0;i<ilosc_testow;i++){
		if((d = fopen(dane[i*3], "r")) == NULL){
			perror(dane[i*3]);
			exit(EXIT_FAILURE);
		}
		int liczba_wierszy = 0;
		char znak;
		// Wpierw trzeba zliczyc wiersze przed alokacja 
		while((znak = getc(d)) != EOF){
			if(znak == '\n'){
			++liczba_wierszy;
			}
		}
//		printf("%i - liczba wierszy\n",liczba_wierszy);

	/*	char** dane_tmp = (char**)malloc(liczba_wierszy*sizeof(char*)); //nie wiadomo jakie to beda dane
		for(j=0;j<liczba_wierszy;j++){
			dane_tmp[j]=(char*)malloc(max*sizeof(char));
		}
		int z = 0;
		while(fscanf(d,"%127s",dane_tmp[z]) != EOF){
			printf("%s\n",dane_tmp[z]);
			z++;
		}
	
	for(j=0;j<liczba_wierszy;j++){
		free(dane_tmp[j]);
	}
	*/
	int* dane_tmp =(int*)malloc(liczba_wierszy*sizeof(int));
	j = 0;
	while(fscanf(d,"%i",dane_tmp[j]) != EOF){
		j++;
	}
	for(j=0;j<liczba_wierszy;j++){
		printf("%i\n",dane_tmp[j]);
	}
	printf("\n");
	free(dane_tmp);
	fclose(d);
	}//end for(i=0;i<ilosc_testow;i++)

dane[i*3] - w każdym wywołaniu pętli wskazuje na nazwę pliku z tablicy charów (sprawdzałem printfem i wszystko było OK). W każdym z tych plików znajdują się wartości (1 wartość przypada na 1 wiersz).

0
fscanf(d,"%i",&(dane_tmp[j]))
0

Hmm, to najwyraźniej nie w tym problem leży

0

Przede wszystkim pilnuj równych wcięć, w połowie kodu nagle się wcięcie zmienia co wygląda niezbyt estetycznie -> źle się to czyta -> programowanie to w 90% czytanie kodu -> źle się programuje...

Po drugie:

fscanf(d,"%i",dane_tmp[j]

To jest stuprocentowy błąd, jeśli nie wywala aplikacji to tylko dlatego że masz szczęście. Musi być, jak podał Shalom, '&':

fscanf(d,"%i",&(dane_tmp[j]))

Po trzecie, jednak faktycznie nie wywala aplikacji bo odczytywanie się nigdy nie wykonuje:

while((znak = getc(d)) != EOF) {
    ...
}
... // w tym momencie plik jest odczytany w całości, nie robisz nic żeby wrócić na początek.
while(fscanf(d,"%i",dane_tmp[j]) != EOF) {
}

Proponuję tam dodać jakieś

fseek(d, 0, SEEK_SET);
0

Rzeczywiście nie pomyślałem, że po zliczaniu wierszy należałoby ustawić pozycję w pliku na jej początek. Dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1