[C]dziwny wyciek pamieci

[C]dziwny wyciek pamieci
brick0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
0

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

Kopiuj
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?

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
0

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

brick0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
0

caly kod:

Kopiuj
/* 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 :/

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Kopiuj
                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.

brick0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
0
MarekR22 napisał(a)

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

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

poradzisz, jak to zalatac?

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
0
Kopiuj
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.

brick0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
0

a jakies free() i czego powinienem zrobic?

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
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.

brick0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
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.

  • Rejestracja: dni
  • Ostatnio: dni
0

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

  • Rejestracja: dni
  • Ostatnio: dni
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?

  • Rejestracja: dni
  • Ostatnio: dni
0

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

brick0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
0
Kopiuj
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

Kopiuj
char tymczasowa[250];

co nie jest dobrym rozwiazaniem, a funkcja przybrala postac:

Kopiuj
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));
}

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.