Funkcja zastępuje wszystkie elementy tablicy, a nie powinna

0

Witam!
Mam pewien problem z swoją funkcją, chodzi dokładnie o to że jest tam sobie pętla zagnieżdzona w drugiej pętli, i one operują na dwóch tablicach dwuwymiarowych, w jakiś sposób przekształcając jej wspólne elementy. Dokładniej funkcja ma za zadania nałożyć jeden obrazek na drugi. Ładuje jeden obrazek(640x640)(argument funkcji) i potem próbuję nałożyć na niego drugi(powiedzmy 25x25) i wtedy, te pierwsze 25x25 jest zrobione dobrze, natomiast reszta pozostaje biała, żeby było jeszcze ciekawiej, okazuje się że skrajne piksele na każdym boku zostają bez zmian.
Wzór na nakadanie jeszcze dopracuję, ale chciałem najlepiej zobaczyć jak to będzie wyglądać...
i i j są dobre, wyświetliłem je wszystkie po kolei i pasowało.
[code]
typedef struct pgm_file{
char file_name_in[FILE_NAME_MAX_LENGHT]; //Nazwa pliku wejsciowego
char file_name_out[FILE_NAME_MAX_LENGHT]; //Nazwa pliku wyjsciowego
int sizex; //Szerokosc obrazu
int sizey; //Wysokosc obrazu
int grayscale; //Skala szarosci obrazu
int display;
FILE *file; //Wskaznik na plik
int **picture; //Dwuwymiarowa tablica informacji o poszczegolnych pikselach obrazu
int debug; //Zmienna logiczna, przechowuje informacje czy pokazywac dodatkowe komunikaty
} pgm;

void cover(pgm **pgm_file, char *name)
{
pgm sec_file;
sec_file=(pgm
) malloc(sizeof(pgm));
strcpy(sec_file->file_name_in, name);
sec_file->debug=(*pgm_file)->debug;
if(!load_file(&sec_file))
{
int i,j;
for(i=(min((*pgm_file)->sizey, sec_file->sizey)-1);i>=0;i--)
{
for(j=(min((*pgm_file)->sizex, sec_file->sizex)-1);j>=0;j--)
{
(pgm_file)->picture[i][j]=(((sec_file->picture[i][j])(((*pgm_file)->grayscale)-((*pgm_file)->picture[i][j])))/(sec_file->grayscale));
}
}
_DEBUG("Covering finished \n");
}
free(sec_file);
}
[/code]

Dla obrazków o tych samych wymiarach również funkcjia działa dobrze.

0

Mam wrażenie deja vu, na tym samym forum, ten sam kod, ten sam problem, na niewłaściwa funkcje narzekanie.

0

Pisałem kiedyś w sprawie tego samego programu, innej jego części, ale problem był zupełnie inny. Wtedy nie ładowało wcale obrazka, tzn źle z wskaźnikami zrobiłem, okazało się że *pgm_file było wskaźnikiem na NULL, teraz ta kwestia działa, mogę np. normalnie wyświetlić co chcę. Inne funkcje zbudowane na podwójnych wskaźniku również bez problemu działają, niestety tutaj chcąc zedytować tylko pewien wycinek obrazka, edytuje cały prawie plik...
Oczywiście problem dotyczył wtedy innej funkcji
Chyba że nie chodziło o mnie tylko innego studenta, to jedno z zadań na uczelnię, więc możliwe że nie jedyny napotkałem taki problem.

Chodzi o ten temat chyba Funkcja zmienia wartości komórek tablicy choć nie powinna ?

[code]
/main.C/
pgm pgm_file;
pgm_file=(pgm
) malloc(sizeof(pgm));
[/code]
[code]
/* pgm_file.C funkcja load_file*/
(pgm_file)->picture = (int*)malloc((pgm_file)->sizey * sizeof(int));
for (int i = 0; i < (*pgm_file)->sizey; i++)
(pgm_file)->picture[i] = (int) malloc((*pgm_file)->sizex * sizeof(int));
[/code]

0

Zacznij od wyniesienia tych min'ów przed pętlami. zrobienie pętli po bożemu do przodu oraz wyświetlenie w _DEBUG(...) wartości tych min'ow.

0

Malloc przydziela pamięć, tak nawet jest napisane na wikipedii, tak mówili wykładowcy etc. Przynajmniej ja to tak zrozumiałem...
[code]
void cover(pgm **pgm_file, char *name)
{
pgm sec_file;
sec_file=(pgm
) malloc(sizeof(pgm));
strcpy(sec_file->file_name_in, name);
sec_file->debug=(*pgm_file)->debug;
if(!load_file(&sec_file))
{
int i,j,x,y;
y=min((*pgm_file)->sizey, sec_file->sizey);
x=min((*pgm_file)->sizex, sec_file->sizex);
printf("x:%d, y:%d",x,y);
for(i=0;i<y;i++)
for(j=0;j<x;j++)
(pgm_file)->picture[i][j]=(((sec_file->picture[i][j])(((*pgm_file)->grayscale)-((*pgm_file)->picture[i][j])))/(sec_file->grayscale));
_DEBUG("Covering finished \n");
}
free(sec_file);
}
[/code]
Efekt: http://imageshack.us/photo/my-images/46/ballonscfeep.png/
W konsoli x: 24 y:7

0

Rzeczywiście ta nową strukturą nadpisuje starą O.o
Kompilator podstawia pod _DEBUG(x) if((*pgm_file->debug) printf(x)
Natomiast gdy usunę tą linijkę z sec_file->debug=(*pgm_file)->debug; to komunikaty się "niepotrzebnie" wyświetlają...
Ale nawet gdy usunę free, to później nie są już dalej wyświetlane...
Nic muszę chyba jeszcze doczytać co nieco o rezerwowaniu pamięci...

0

A pokaż mi jak preparujesz to name które dostaje ta funkcja. Akurat z przydzieleniem pamięci tu masz dobrze.

0

Wywołanie funkcji cover:
[code]
if(i+1!=argc && argv[i+1][0]!='-')
cover(pgm_file, argv[i+1]);
else
fprintf(stderr, "Covering, missing file name, no action taken \n");
break;
[/code]
Funkcja load_file()
[code]
int load_file(pgm **pgm_file)
{
(*pgm_file)->file=fopen((*pgm_file)->file_name_in, "r+");
if((*pgm_file)->file==NULL)
{
fprintf(stderr, "Load_file: Loading file failed, check file name and permissions, then try again. \n");
abort();
}
else
{
_DEBUG("Load file: File opened successfully \n");
char string[FILE_MAX_CHARS_IN_LINE];
int i, j, symbol;

	/* Sprawdzenie czy pierwsza linia nie jest pusta */
	if (fgets(string,FILE_MAX_CHARS_IN_LINE,(*pgm_file)->file)==NULL)
	{
		fprintf(stderr, "Load_file: File seems to be empty \n");
		fclose((*pgm_file)->file);
		return 1;
	}
	_DEBUG("Load file: First line : passed \n")
	
	/* Sprawdzenie czy znak magiczny sie zgadza */
	if(string[0]!='P' || string[1]!='2')
	{
		fprintf(stderr, "Load_file: File is not proper pgm_file. Magic number check failed. \n");
		fclose((*pgm_file)->file);
		return 2;
	}
	_DEBUG("Load file: Magic number : passed \n")
	
	/* Przepuszczenie komentarza*/
	do{
			if((symbol=fgetc((*pgm_file)->file))=='#')
			{
				fgets(string,FILE_MAX_CHARS_IN_LINE, (*pgm_file)->file);
			}
			else
			{
				ungetc(symbol, (*pgm_file)->file);
				/* Jezeli nie ma juz komentatrza to zwroc ostatni pobrany znak, bo prawdopodobnie jest to pierwsza cyfra szerokosci pliku, a ta jeszcze sie przyda */
			}		
	}while(!symbol=='#');   
	_DEBUG("Load file: comments removed \n");
	
	/* Pobranie szerokosci, wysokosci i skali szarosci*/
	if (fscanf((*pgm_file)->file,"%d %d %d",&(*pgm_file)->sizex,&(*pgm_file)->sizey,&(*pgm_file)->grayscale)!=3)
	{
		fprintf(stderr,"Load_file: Size or grayscale invalid \n");
		fclose((*pgm_file)->file);
		return 3;
	}
	_DEBUG("Load file: size and grayscale loaded \n");
	
	/*	Zaalokowanie pamieci pod tablice dwuwymiarowa z pikselami */
	(*pgm_file)->picture = (int**)malloc((*pgm_file)->sizey * sizeof(int*));
	for (int i = 0; i < (*pgm_file)->sizey; i++)
		(*pgm_file)->picture[i] = (int*) malloc((*pgm_file)->sizex * sizeof(int));
	_DEBUG("Load file: Memory malloc successed \n");
	/* Wypelnienie tablicy dwuwymiarowej odpowiednimi danymi */
	for(i=0;i<((*pgm_file)->sizey);i++)
	{
		for(j=0;j<((*pgm_file)->sizex);j++)
		{
			if (fscanf((*pgm_file)->file,"%d",&((*pgm_file)->picture[i][j]))!=1)
			{
				fprintf(stderr,"Load_file: Wrong size of the picture. Try another file \n");
				fclose((*pgm_file)->file);
				return 4;
			}
		}
	}
	_DEBUG("Load file: Loading finished successfully \n");
}
fclose((*pgm_file)->file);
return 0;

}
[/code]

/edit
Może on nie alokuje pamięci pod zmienną na którą wskazuje pgm_file->file (wskaźnik do pliku samego w sobie)? i pisze sobie ją w powietrzu, po pewnym czasie napotykając tablicę, i wtedy nie pisze już w powietrzu tylko po mojej tablicy?

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