Zwracanie stringa w funkcji (Język C)

0

Witam wszystkich!
Mam problem z kodem zamieszczonym niżej. Otóż po wywołaniu funkcji są jakieś błędy w pamięci i "krzaczy" pierwsze kilka znaków w stringu, potem jest ok. Czy w zły sposób alokuje i zwalniam pamięć? Proszę o pomoc i jakieś wskazówki :)

char *szyfruj(char *tekst, uint e, uint modul){
	int *tabkod, *tabzakod;		//tablice do zapisywania pojedyńczych znaków niezakodowanych i zakodowanych
	int dlugosc = strlen(tekst);	//liczba wyrazów w tekscie
	int i; 
	int liczbacyfr=0;	//zmienna zliczaja liczbe cyfr w kodzie zaszyfrowanym
	char *wiadomosc;	//zmienna zwracajac tekst zaszyfrowany
	char *temp;			//zmienna tymczasowa do przechowywania pojedynczego znaku
	tabkod = (int*)malloc(dlugosc * sizeof *tabkod);
	tabzakod = (int*)malloc(dlugosc * sizeof *tabzakod);
	for(i=0;i<dlugosc;++i){
		tabkod[i]=(int)tekst[i];	//operacja rzutowania z char na int
		tabzakod[i]=pot_mod(tabkod[i],e,modul);
		liczbacyfr=liczbacyfr+ilecyfr(tabzakod[i]);
		printf("%i", ilecyfr(tabzakod[i]));
    }
    wiadomosc = (char*)malloc((ilecyfr(dlugosc)+dlugosc+liczbacyfr+1) * sizeof *wiadomosc);
    sprintf(wiadomosc, "%d", dlugosc);
    strcat(wiadomosc," ");
    for(i=0;i<dlugosc;++i){
		temp=(char*)malloc(ilecyfr((tabzakod[i]+1)) * sizeof *temp);
		sprintf(temp, "%d", tabzakod[i]);
		strcat(wiadomosc,temp);
		strcat(wiadomosc," ");
		free(temp);
}
    /*
    printf("Ile cyfr %i\n", liczbacyfr);
    printf("Licznik: %i\n", dlugosc);
    for(i=0;i<dlugosc;++i){
		printf("%i ", tabzakod[i]);
    }
    */
    free(tabkod);
    free(tabzakod);
    free(wiadomosc);
    return wiadomosc;
} 

//edit
Wrzucam też cały kod http://4programmers.net/Pastebin/2802

0
tabkod=(int*)malloc(dlugosc * sizeof(int));
0

A dlaczego nie może być tak jak jest?

 tabkod = (int*)malloc(dlugosc * sizeof *tabkod) 

Generalnie chodzi mi głównie o jedną rzecz. W funkcji szyfruj() chciałem zwrócić tekst. Zmienną która to robi (char *wiadomosc) tworze w funkcji i za pomocą malloca alokuje jej pamięć. I teraz pytanie kiedy mam tą pamięć zwolnić? Jeśli zrobie tak:

 free(tabkod);
    free(tabzakod);
    return wiadomosc;
    free(wiadomosc); 

To wtedy następuje wyciek pamięci. Jeśli znowu zrobie w ten sposób:

 free(tabkod);
    free(tabzakod);
    free(wiadomosc);
    return wiadomosc; 

Zwracana wartość się sypie, czasami całkowicie czasami tylko kilka początkowych wartości. I moje pytanie co robie źle i czy może zabieram się za to od złej strony?

0

Tak na szybko;
return zwaraca wartość z funkcji i w tym momencie ona się już kończy. free(wiadomosc) się po prostu nie wykona. W drugim przypadku jak już zwolnisz to co pod wskaźnikiem wiadomosc to potem zwracasz jakieś dzikie dane na które wskazuje ten wiszący wskaźnik. nie czytałam 1 postu, ale najlepiej zrobić sobie funkcję zwracającą stringa http://stackoverflow.com/questions/252782/strdup-what-does-it-do-in-c a potem w main() char *string = strdup("costam"); i pod koniec tylko free(string);

tak btw - do sprawdzania wycieków używasz valgrind?

0

Nie możesz zwolnić ani przed return'em bo zwolnisz zwracaną pamięć ani po returnie bo zwyczajnie się nie wykona.
Możesz zrobić taki trik:

static char *wiadomosc=NULL;
...
wiadomosc=realloc(wiadomosc,jakis_rozmiar);
...
return wiadomosc;
0
karolinaa napisał(a):

Tak na szybko;
return zwaraca wartość z funkcji i w tym momencie ona się już kończy. free(wiadomosc) się po prostu nie wykona. W drugim przypadku jak już zwolnisz to co pod wskaźnikiem wiadomosc to potem zwracasz jakieś dzikie dane na które wskazuje ten wiszący wskaźnik. nie czytałam 1 postu, ale najlepiej zrobić sobie funkcję zwracającą stringa http://stackoverflow.com/questions/252782/strdup-what-does-it-do-in-c a potem w main() char *string = strdup("costam"); i pod koniec tylko free(string);

tak btw - do sprawdzania wycieków używasz valgrind?

Z tego co zrozumiałem tworze w main():

char *nowaZmienna;
nowaZmienna = (char*)malloc(strlen(szyfruj(tekst,e,modul) * sizeof(char));
nowaZmienna = strdup(szyfruj(tekst,e,modul));
....jakies operacje....
free(nowaZmienna);

Tylko jeśli ma być tak jak to rozpisałem dalej ta pamięć ucieka :/ Chyba, że chodzi o coś innego...

0
_13th_Dragon napisał(a):

Nie możesz zwolnić ani przed return'em bo zwolnisz zwracaną pamięć ani po returnie bo zwyczajnie się nie wykona.
Możesz zrobić taki trik:

static char *wiadomosc=NULL;
...
wiadomosc=realloc(wiadomosc,jakis_rozmiar);
...
return wiadomosc;

Dobra mam taki kawałek kodu u siebie i stosując twoje rozwiązanie robie w ten sposób:

  static char *wiadomosc = NULL;
.....kod.....
 temp=(char*)malloc(ilecyfr((tabzakod[i]+1)) * sizeof *temp);
sprintf(temp, "%d", tabzakod[i]);
wiadomosc = realloc(wiadomosc, (strlen(temp)+1) * sizeof(char));
strcat(wiadomosc,temp);
strcat(wiadomosc," ");
free(temp);
.....kod....
return wiadomosc;
.....koniec funkcji.....

I pamięć dalej ucieka :( Albo ja już coś źle pacze z tym Valgrindem

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