Zwalnianie pamięci której wskaźnik został zmodyfikowany

0

Witam!

Mam następujący problem. W poniższym kodzie przy próbie uruchomienia wyskakuje komunikat:
glibc detected *** ./a.out: free(): invalid next size (fast): 0x099a90a0 ***
Z tego co wyczytałem dzieję się tak ponieważ staram się zwolnić miejsce w pamięci na które dany wskaźnik już nie wskazuje ponieważ zostały wykonane na nim jakieś operacje. Co lepsze gdy uruchomie kod pod Valgrindem, nie pojawiają się żadne błędy! :/ W czym jest problem?
Proszę o jakieś rady albo 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
	char temp1[20];
    int i; 
	int liczbacyfr=0;	//zmienna zliczaja liczbe cyfr w kodzie zaszyfrowanym
	char *wiadomosc;	//zmienna zwracajac tekst zaszyfrowany
	static char msgszyfr[4092];
	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]);
    }
    wiadomosc = (char*)malloc((ilecyfr(dlugosc)+dlugosc+liczbacyfr+1) * sizeof *wiadomosc);
    for(i=0;i<dlugosc;++i){
		sprintf(temp1, "%d", tabzakod[i]);
		strcat(wiadomosc,temp1);
		strcat(wiadomosc,"$");
		memset(temp1, 0x00, 20);
}
	strcpy(msgszyfr, wiadomosc);
    free(tabkod);
    free(tabzakod);
    free(wiadomosc);
    return msgszyfr;
} 
0

A pewny jesteś ze to tutaj jest problem? No ma pierwszy rzut oka tutaj alokacje są ok.

0

Gdzieś mażesz po pamięci, ot tyle.

0

Mam jeszcze drugą funkcje która może powodować problem

char *rozszyfruj(char *tekst2, uint d, uint modul){
	int *tabkod, *tabodkod;		//tablice do zapisywania pojedyńczych znaków niezakodowanych i zakodowanych
	char *token;
	char *string;
	char *tofree;
	char *tekstfinal;
	static char msgodszyfr[ROZMIAR];
	int licznik=0,i=0,j=0;
	
	//ile elementow tabllicy trzeba zaalokować w pamieci
	for(i=0;i<strlen(tekst2);++i){
			if((int)tekst2[i] == 36) j++;
	}
	
	//alokacja pamieci dla dwóch tablic z których jedna jest zakodowana, druga ma odkodowane liczby ASCII
	tabkod = (int*)malloc((j+1) * sizeof *tabkod);
	tabodkod = (int*)malloc((j+1) * sizeof *tabodkod);
	
	//cięcie stringa na kawałki, separatorem jest $
	string = strdup(tekst2);
	if (string != NULL) {
	tofree = string;
	while ((token = strsep(&string, "$")) != NULL)
	{
		tabkod[licznik]=strtol(token, NULL, 10);	//zapisuje podzielony tekst pod indeks tablicy
		licznik++;
	}
	free(tofree);
    }	
	//odkodowanie i zapis do tablic
	for(i=0;i<(j+1);++i){
		tabodkod[i]=pot_mod(tabkod[i],d,modul);
    }
    
    //alokacja zwracanej tablicy
    tekstfinal = (char*)malloc(licznik * sizeof *tekstfinal);
    
    //wyświetlnie wiadomości! :)
    for(i=0;i<licznik;++i){
		tekstfinal[i]=(char)tabodkod[i];
    }
    strcpy(msgodszyfr, tekstfinal);
    //zwalniam pamiec
    free(tabkod);
    free(tabodkod);
    free(tekstfinal);
    return msgodszyfr;

}
1

O boże! Oto twoja rozszyfruj napisana po ludzku:

char *rozszyfruj(char *text, uint d, uint modul)
  {
   static char msgodszyfr[ROZMIAR];
   char *ptr=msgodszyfr;
   for(ptr=msgodszyfr;*text;++text) *(ptr++)=(char)pot_mod(strtoul(text,&text,10),d,modul);
   *ptr=0;
   return msgodszyfr;
  }

No nie zupełnie po ludzku, msgodszyfr oraz ROZMIAR trzeba przyjąć jako dodatkowe parametry.

Ale potrafisz rozpisać swoją myśl na kilka stron, zastanów się nad dziennikarstwem.

0

@_13th_Dragon pewnie słyszałeś to wiele razy ale JESTEŚ MISTRZEM! :)

Ale problem z pamięcią dalej występuje... :(
Tutaj wrzucam output Valgrinda

 ==2949== Memcheck, a memory error detector
==2949== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==2949== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==2949== Command: ./a.out
==2949== Parent PID: 2774
==2949== 
--2949-- 
--2949-- Valgrind options:
--2949--    --suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp
--2949--    -v
--2949--    --tool=memcheck
--2949--    --leak-check=full
--2949--    --show-reachable=yes
--2949--    --log-file=filename.txt
--2949-- Contents of /proc/version:
--2949--   Linux version 3.2.0-4-686-pae ([email protected]) (gcc version 4.6.3 (Debian 4.6.3-14) ) #1 SMP Debian 3.2.51-1
--2949-- Arch and hwcaps: X86, x86-sse1-sse2
--2949-- Page sizes: currently 4096, max supported 4096
--2949-- Valgrind library directory: /usr/lib/valgrind
--2949-- Reading syms from /lib/i386-linux-gnu/ld-2.13.so (0x4000000)
--2949--   Considering /lib/i386-linux-gnu/ld-2.13.so ..
--2949--   .. CRC mismatch (computed 734636b7 wanted cf830bae)
--2949--   Considering /usr/lib/debug/lib/i386-linux-gnu/ld-2.13.so ..
--2949--   .. CRC is valid
--2949-- Reading syms from /home/me/AP/a.out (0x8048000)
--2949-- Reading syms from /usr/lib/valgrind/memcheck-x86-linux (0x38000000)
--2949--   Considering /usr/lib/valgrind/memcheck-x86-linux ..
--2949--   .. CRC mismatch (computed f9c53117 wanted 8a91a8b2)
--2949--   Considering /usr/lib/debug/usr/lib/valgrind/memcheck-x86-linux ..
--2949--   .. CRC is valid
--2949--    object doesn't have a dynamic symbol table
--2949-- Reading suppressions file: /usr/lib/valgrind/debian-libc6-dbg.supp
--2949-- Reading suppressions file: /usr/lib/valgrind/default.supp
==2949== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-2949-by-me-on-???
==2949== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-2949-by-me-on-???
==2949== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-2949-by-me-on-???
==2949== 
==2949== TO CONTROL THIS PROCESS USING vgdb (which you probably
==2949== don't want to do, unless you know exactly what you're doing,
==2949== or are doing some strange experiment):
==2949==   /usr/lib/valgrind/../../bin/vgdb --pid=2949 ...command...
==2949== 
==2949== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==2949==   /path/to/gdb ./a.out
==2949== and then give GDB the following command
==2949==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=2949
==2949== --pid is optional if only one valgrind process is running
==2949== 
--2949-- REDIR: 0x4016a40 (strlen) redirected to 0x38055304 (vgPlain_x86_linux_REDIR_FOR_strlen)
--2949-- REDIR: 0x4016860 (index) redirected to 0x380552df (vgPlain_x86_linux_REDIR_FOR_index)
--2949-- Reading syms from /usr/lib/valgrind/vgpreload_core-x86-linux.so (0x4021000)
--2949--   Considering /usr/lib/valgrind/vgpreload_core-x86-linux.so ..
--2949--   .. CRC mismatch (computed bbadfadd wanted 39de28c9)
--2949--   Considering /usr/lib/debug/usr/lib/valgrind/vgpreload_core-x86-linux.so ..
--2949--   .. CRC is valid
--2949-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so (0x4024000)
--2949--   Considering /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so ..
--2949--   .. CRC mismatch (computed 9b401e29 wanted 9e97adf8)
--2949--   Considering /usr/lib/debug/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so ..
--2949--   .. CRC is valid
--2949-- Reading syms from /lib/i386-linux-gnu/i686/cmov/libc-2.13.so (0x4043000)
--2949--   Considering /lib/i386-linux-gnu/i686/cmov/libc-2.13.so ..
--2949--   .. CRC mismatch (computed d8985af8 wanted 94fea1aa)
--2949--   Considering /usr/lib/debug/lib/i386-linux-gnu/i686/cmov/libc-2.13.so ..
--2949--   .. CRC is valid
--2949-- REDIR: 0x40bc410 (rindex) redirected to 0x4028600 (rindex)
--2949-- REDIR: 0x40b8890 (malloc) redirected to 0x40282a0 (malloc)
--2949-- REDIR: 0x40bebb0 (strchrnul) redirected to 0x402aee0 (strchrnul)
--2949-- REDIR: 0x40b87b0 (free) redirected to 0x40274a0 (free)
--2949-- REDIR: 0x40bc0f0 (__GI_strlen) redirected to 0x4028a60 (__GI_strlen)
--2949-- REDIR: 0x40bcca0 (memchr) redirected to 0x40296f0 (memchr)
--2949-- REDIR: 0x40bc0a0 (strlen) redirected to 0x40215c0 (_vgnU_ifunc_wrapper)
--2949-- REDIR: 0x40c2ac0 (__strlen_sse2_bsf) redirected to 0x4028a40 (strlen)
--2949-- REDIR: 0x40bb790 (strcat) redirected to 0x4028720 (strcat)
==2949== Conditional jump or move depends on uninitialised value(s)
==2949==    at 0x402873C: strcat (mc_replace_strmem.c:254)
==2949==    by 0x8048D8E: szyfruj (rsa.c:147)
==2949==    by 0x8048F56: main (rsa.c:233)
==2949== 
--2949-- REDIR: 0x40bd230 (memset) redirected to 0x40215c0 (_vgnU_ifunc_wrapper)
--2949-- REDIR: 0x415a890 (__memset_sse2) redirected to 0x402aba0 (memset)
--2949-- REDIR: 0x40bbb70 (strcpy) redirected to 0x4028a80 (strcpy)
==2949== 
==2949== HEAP SUMMARY:
==2949==     in use at exit: 0 bytes in 0 blocks
==2949==   total heap usage: 4 allocs, 4 frees, 518 bytes allocated
==2949== 
==2949== All heap blocks were freed -- no leaks are possible
==2949== 
==2949== Use --track-origins=yes to see where uninitialised values come from
==2949== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)
==2949== 
==2949== 1 errors in context 1 of 1:
==2949== Conditional jump or move depends on uninitialised value(s)
==2949==    at 0x402873C: strcat (mc_replace_strmem.c:254)
==2949==    by 0x8048D8E: szyfruj (rsa.c:147)
==2949==    by 0x8048F56: main (rsa.c:233)
==2949== 
--2949-- 
--2949-- used_suppression:     11 U1004-ARM-_dl_relocate_object
==2949== 
==2949== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)

 
1

No ale czego tu nie rozumiesz? Masz napisane wyraźnie że z pamięcią jest ok, ale:

==2949== Conditional jump or move depends on uninitialised value(s)
==2949== at 0x402873C: strcat (mc_replace_strmem.c:254)
==2949== by 0x8048D8E: szyfruj (rsa.c:147)
==2949== by 0x8048F56: main (rsa.c:233)

I też nie dziwota. Wiesz jak dziala strcat? Nie? To doczytaj. On dopisuje "na końcu" C-stringa podaną wartość. Koniec C-stringa określa bajt \0. U ciebie tego bajtu NIE MA bo go tam wcale nie wstawiłeś.

0

Zapisz szyfruj w tej samej konwencji co przykład dałem i wszystko będzie grać.

0

Ok, dzięki sprobuje to zakodzić i jutro wrzucę wyniki mojej pracy :)

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