[C]dziwny wyciek pamieci

0

Witam,
otwierajac, a nastepnie zamykajac folder, zauwazylem dziwny wyciek pamieci:

char * listuj(char * katalog)
{
DIR * folder;
struct dirent * znaleziony;

folder = opendir (katalog);
...
closedir(folder);
return NULL;
}

odpowiedz valgrinda:

4,120 bytes in 1 blocks are possibly lost in loss record 3 of 3
at 0x4006ADE: malloc (vg_replace_malloc.c:207)
by 0x424322BA: (within /lib/i686/libc-2.8.so)
by 0x42432452: opendir (in /lib/i686/libc-2.8.so)
by 0x8049625: listuj (poczta.c:85)
by 0x80492DB: sprawdzaj_poczte (poczta.c:16)
by 0x8048C00: main (main.c:90)

ma ktos pomysl, jak zlikwidowac ten wyciek?

0

Wygląda dobrze. Może cieknie gdzieś w miejscu wielokropka.
Jeśli masz wątpliwości napisz test modułowy.

0

caly kod:

/* wyszukuje nowe pliki w katalogu */
char * listuj(char * katalog)
{
DIR * folder;
struct dirent * znaleziony;

folder = opendir (katalog);
if (folder != NULL)
	{
	while ((znaleziony = readdir (folder)))
		{
		if(strcmp(znaleziony->d_name,".")!=0 && strcmp(znaleziony->d_name,"..")!=0)
			return znaleziony->d_name;
		}
	closedir(folder);
	}
else
	{
	logi_dodaj(10,katalog);
	}
return NULL;
}

pisalem test... na samym main() jest to samo :/

0

no właśnie widać wyciek od razu:

                if(strcmp(znaleziony->d_name,".")!=0 && strcmp(znaleziony->d_name,"..")!=0)
                        return znaleziony->d_name;

a dokładniej jeśli warunek jest spełniony to nie wykonasz closedir.

0
MarekR22 napisał(a)

no właśnie widać wyciek od razu:

                if(strcmp(znaleziony->d_name,".")!=0 && strcmp(znaleziony->d_name,"..")!=0)
                        return znaleziony->d_name;

poradzisz, jak to zalatac?

0
char * listuj(char * katalog)
{
DIR * folder;
struct dirent * znaleziony;

char *result = NULL;

folder = opendir (katalog);
if (folder != NULL)
        {
        while ((znaleziony = readdir (folder)))
                {
                if(strcmp(znaleziony->d_name,".")==0 || strcmp(znaleziony->d_name,"..")==0)
                        continue;
                result = // tu robisz kopię nazwy na stercie 
                }
        closedir(folder);
        return result;
        }
else
        {
        logi_dodaj(10,katalog);
        }
return NULL;
}

Chyba łapiesz, że musisz zrobić kopię nawy, którą chcesz zwrócić a potem użytkownik listuj jest odpowiedzialny za zwolnienie tego napisu ze sterty.

0

a jakies free() i czego powinienem zrobic?

0

Wszystko zależy jak planujesz zaprojektować tą metodę (listuj). Ja bym napisał tak, że zwraca ona ownership napisu do wywołującego ją kodu.

A i jeszcze strzeliłem byka w kodzie (już poprawiłem wyżej), nie aktualizując warunku.

0
MarekR22 napisał(a)

Ja bym napisał tak, że zwraca ona ownership napisu do wywołującego ją kodu.
A i jeszcze strzeliłem byka

Zauwazylem, mniejsza o wiekszosc. nadal nie wiem, jak to napisac. ogolnie mialem wielkie problemy, jak mi wykladowca kazal pozwalniac pamiec, po tym, jak mi "przelecial" valgrindem kodzik. wszystkie mallocki zamienilem na tablice znakow, zeby to ominac, bo mialem Segmentaton przy kazdym zwalnianiu. najchetniej to bym Ci podeslal caly program, zebys rzucil okiem, ale nie widze Twojego maila nigdzie.

0

A może by tak przekazywać do funkcji bufor? Wtedy pełną kontrolę ma właściciel...

0
asdf napisał(a)

A może by tak przekazywać do funkcji bufor?

A mozesz podac jakis przyklad, zeby to zobrazowac? Chodzi Ci o przekazanie adresu do zmiennej do funkcji, zeby na niej operowac?

0

No jak, jak w strcpy chociażby...

0
char * odbiorca(char * nazwa_pliku)
{
FILE * plik;
int i;
char * linia=malloc(250);

plik=fopen(nazwa_pliku,"r");
for(i=0;i<2;i++)
	fgets(linia,MAX_LINIA,plik);
fclose(plik);
linia=strtok(linia,": ");
linia=strtok(NULL," @");
return linia;
}

jak zwolnic zmienna "linia"? rozwiazalem to w ten sposob, ze korzystam ze zmiennej globalnej

char tymczasowa[250];

co nie jest dobrym rozwiazaniem, a funkcja przybrala postac:

void odbiorca(char * nazwa_pliku)
{
FILE * plik;
int i;
char linia[250];

plik=fopen(nazwa_pliku,"r");
for(i=0;i<2;i++)
	fgets(linia,MAX_LINIA,plik);
fclose(plik);
strcpy(linia,strtok(linia,": "));
strcpy(linia,strtok(NULL," @"));
strncpy(tymczasowa,linia,sizeof(linia));
}

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