Sortowanie przez wstawianie - Naruszenie ochrony pamieci

0

Witajcie.
Muszę napisać program, który będzie wczytywał od użytkownika nazwę pliku z liczbami, następnie będzie sortował liczby i wypisze je posortowane do drugiego pliku podanego przez użytkownika.

Na chwilę teraźniejszą mam tyle kodu i wyskakuje mi błąd "Naruszenie ochrony pamięci"
Mój system to ubuntu 11.10
kompiluje z opcjami -ansi -pedantic -W -Wall

A oto kod:

#include <stdio.h>
#include <stdlib.h>

int main()
{
char zrodlowy[10];
char docelowy[10];
long rozmiar;
int i, tablica[sizeof(rozmiar)];
FILE *plik1;
FILE *plik2;
	
	printf("Podaj nazwe pliku zrodlowego.\n");
	scanf("%s",zrodlowy);
	printf("pobralem zrodlowy \n");	
	
	plik1 = fopen(zrodlowy,"r");
	if (plik1 == NULL)
	{
		printf("\tPodany plik nie istnieje\n");
		return -1;
	}
	else
	{	
		i = 0;
		rozmiar = 0;
		while(!feof(plik1))
		{
			fscanf(plik1,"%d",&tablica[i]);
			i++;
			rozmiar++;	
		}
	
		printf("Podaj nazwe pliku docelowego.\n");
		scanf("%s",docelowy);
		printf("pobralem docelowy\n");
		plik2 = fopen(docelowy,"w");		

		for (i=0;i<=rozmiar;i++)
		{
			fprintf(plik2, "%d\n",tablica[i]);
		}
	}	
	fclose(plik1);
	fclose(plik2);
return 0;
} 

Program pobiera nazwę pliku zrodlowego i wywala blad.


EDIT:
Znalazłem błąd - linijka z deklaracją tablicy.
Czy macie może jakiś pomysł jak zadeklarować rozmiar tablicy "nie na sztywno"?

0

Poczytaj o malloc

0

Poczytaj o tablicach dynamicznych:

size_t i,rozmiar=0,zapas=16;
int v,*tablica=(int*)malloc(zapas*sizeof(int));

while(fscanf(plik1,"%d",&v)==1)
  {
   if(rozmiar>=zapas)
     {
      int *tmp=(int*)malloc((zapas+=16)*sizeof(int));
      memcpy(tmp,tablica,rozmiar*sizeof(int));
      delete[] tablica;
      tablica=tmp;
     }
   tablica[rozmiar++]=v;
  }
0

poczytałem o mallocu - przydatna sprawa :)

dopisałem coś takiego :

 int rozmiar, i; 
int *tablica = (int*)malloc(rozmiar * sizeof(tablica));

oraz dopisałem na końcu programu free(tablica);
Teraz program przy kompilowaniu wywala warning z rozmiarem :
warning: ‘rozmiar’ is used uninitialized in this function [-Wuninitialized] - chodzi o linijke z malloc

Gdy przy deklaracji rozmiaru dam mu wartość np 0, to ostrzeżenie znika, ale program znowu głosi o naruszenie ochrony pamięci.

0

Chodzi o to że musisz w tym rozmiar mieć konkretną liczbę.
Podałem ci wyżej deklaracje oraz pętle wczytującą.

0

Nastąpiła zmiana polecenia.
Tablica ma być na sztywno 1000 elementowa.
Pokombinowałem i program przepisuje mi z 1 pliku do 2 pliku liczby ale ich nie sortuje.

#include <stdio.h>
#include <stdlib.h>

int main()
{
char zrodlowy[10];
char docelowy[10];
int rozmiar=1000, i, j, wartosc; 
int tablica[rozmiar];
FILE *plik1;
FILE *plik2;
	
	/*tablica = (int*)malloc(rozmiar * sizeof(int));*/
	printf("Podaj nazwe pliku zrodlowego.\n");
	scanf("%s",zrodlowy);
	printf("pobralem zrodlowy \n");	
	
	plik1 = fopen(zrodlowy,"r");
	if (plik1 == NULL)
	{
		printf("\tPodany plik nie istnieje\n");
		return -1;
	}
	else
	{	
		i = 0;
		rozmiar = 0;		
		while(!feof(plik1))
		{		
			fscanf(plik1,"%d",&tablica[i]);
			i++;
			rozmiar++;	
		}
		for(i=1;i<rozmiar;i++)
		{
			wartosc = tablica[i];
			for(j=i;(j>0)&&(tablica[j]>wartosc);j++)
			{
				tablica[j]=tablica[j-1];
			}
			tablica[j] = wartosc;
		}		
	
		printf("Podaj nazwe pliku docelowego.\n");
		scanf("%s",docelowy);
		printf("pobralem docelowy\n");
		plik2 = fopen(docelowy,"w");		

		for (i=0;i<rozmiar;i++)
		{
			fprintf(plik2, "%d\n",tablica[i]);
		}
	}	
	fclose(plik1);
	fclose(plik2);
return 0;
} 

Jako winną podejrzewam pętle for, która powinna sortować, a tego nie czyni.

0

Bo ta pętla:

                        wartosc = tablica[i];
                        for(j=i;(j>0)&&(tablica[j]>wartosc);j++)

Nigdy nie zrobi ani jednego kroku.
wartosc=tablica[i], j=i, czy tablica[j]>wartosc ?
nie, ponieważ tablica[i]>tablica[i] - nigdy nie może być prawdą.

0

Faktycznie dziwny zapis miałem
Zamieniłem na takie coś :

for(i=1;i<1000;i++)
		{
			wartosc = tablica[i];
			for(j=i-1;(j>0)&&(tablica[j]>wartosc);--j)
			{
				tablica[j+1]=tablica[j];
			}
			tablica[j+1] = wartosc;
		} 

Przy okazji zamieniłem zmienna rozmiar na 1000
I program zaczął sortować ale od 2 linijki
Pierwsza przepisuje.

0

Napisz tą pętle jeszcze raz, bo w niej nie ma ani jednej sensownej instrukcji.

0

Zamieniłem pętle na taką

 for(i=1;i<1000;++i)
		{
			wartosc = tablica[i];
			for(j=i-1;j>=0 && tablica[j]>wartosc;--j)
			{
				tablica[j+1]=tablica[j];
			}
			tablica[j+1]=wartosc;
		}

I program zaczął działać.

Dzięuję za pomoc i szybkie odpowiedzi

Pozdrawiam Arkadiusz 'aro'

0

No prawie, w pierwszej pętli zwróć rozmiar na jego prawowite miejsce.

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