Uvolnovanie pamate [C]

Sekcia: Programovanie 16.05.2012 | 22:30
Maco   Návštevník
Zdravim.

Program mi bezi bez chyb, no pri ukoncovani, ked sa zavola funkcia free(retazec), sa stane "katastrofa".
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00000000007f188f ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7e626)[0x7f2747e98626]
./a.out[0x402201]
./a.out[0x4009ef]
./a.out[0x400fe4]
./a.out[0x4010a2]
./a.out[0x400fdd]
./a.out[0x4009df]
./a.out[0x4009bd]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f2747e3b76d]
./a.out[0x4008f9]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:01 29360399                             a.out
00602000-00603000 r--p 00002000 08:01 29360399                              a.out
00603000-00604000 rw-p 00003000 08:01 29360399                            a.out
7f2747a00000-7f2747a15000 r-xp 00000000 08:01 24514046                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f2747a15000-7f2747c14000 ---p 00015000 08:01 24514046                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f2747c14000-7f2747c15000 r--p 00014000 08:01 24514046                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f2747c15000-7f2747c16000 rw-p 00015000 08:01 24514046                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f2747c16000-7f2747c18000 r-xp 00000000 08:01 24514038                   /lib/x86_64-linux-gnu/libdl-2.15.so
7f2747c18000-7f2747e18000 ---p 00002000 08:01 24514038                   /lib/x86_64-linux-gnu/libdl-2.15.so
7f2747e18000-7f2747e19000 r--p 00002000 08:01 24514038                   /lib/x86_64-linux-gnu/libdl-2.15.so
7f2747e19000-7f2747e1a000 rw-p 00003000 08:01 24514038                   /lib/x86_64-linux-gnu/libdl-2.15.so
7f2747e1a000-7f2747fcd000 r-xp 00000000 08:01 24514025                   /lib/x86_64-linux-gnu/libc-2.15.so
7f2747fcd000-7f27481cc000 ---p 001b3000 08:01 24514025                   /lib/x86_64-linux-gnu/libc-2.15.so
7f27481cc000-7f27481d0000 r--p 001b2000 08:01 24514025                   /lib/x86_64-linux-gnu/libc-2.15.so
7f27481d0000-7f27481d2000 rw-p 001b6000 08:01 24514025                   /lib/x86_64-linux-gnu/libc-2.15.so
7f27481d2000-7f27481d7000 rw-p 00000000 00:00 0 
7f27481d7000-7f27481f9000 r-xp 00000000 08:01 24514122                   /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f27481f9000-7f27483f9000 ---p 00022000 08:01 24514122                   /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f27483f9000-7f27483fd000 r--p 00022000 08:01 24514122                   /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f27483fd000-7f27483fe000 rw-p 00026000 08:01 24514122                   /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f27483fe000-7f274841d000 r-xp 00000000 08:01 24514063                   /lib/x86_64-linux-gnu/libncurses.so.5.9
7f274841d000-7f274861d000 ---p 0001f000 08:01 24514063                   /lib/x86_64-linux-gnu/libncurses.so.5.9
7f274861d000-7f274861e000 r--p 0001f000 08:01 24514063                   /lib/x86_64-linux-gnu/libncurses.so.5.9
7f274861e000-7f274861f000 rw-p 00020000 08:01 24514063                   /lib/x86_64-linux-gnu/libncurses.so.5.9
7f274861f000-7f2748641000 r-xp 00000000 08:01 24514005                   /lib/x86_64-linux-gnu/ld-2.15.so
7f2748825000-7f2748829000 rw-p 00000000 00:00 0 
7f274883e000-7f2748841000 rw-p 00000000 00:00 0 
7f2748841000-7f2748842000 r--p 00022000 08:01 24514005                   /lib/x86_64-linux-gnu/ld-2.15.so
7f2748842000-7f2748844000 rw-p 00023000 08:01 24514005                   /lib/x86_64-linux-gnu/ld-2.15.so
7fff93d58000-7fff93d79000 rw-p 00000000 00:00 0                          [stack]
7fff93dff000-7fff93e00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)
Nejak takto podobne to vyzera:
char * retazec_1 = "linuxos";
char * retazec;

int main()
{
    funkcia1();
   
    while(*retazec++ != '\0')
       {
       // ...........
       }
   
   funkcia2();
   return 0;
}

void funkcia1()
{
    retazec = (char *)malloc(sizeof(char)*sizeof(*retazec_1)); 
    strcpy(retazec,retazec_1);
}

void funkcia2()
{
  free(retazec );
}

  • Re: Uvolnovanie pamate [C] 16.05.2012 | 23:00
    Maco   Návštevník
    neviem ci je to spravne riesenie, ale mam to takto a teraz nie je problem:

    do funkcia2() som dal
    retazec = NULL;
    

    1) je to ekvivalent free() ?
    2) ako uvolnit pamat funkciou free()?
    • Re: Uvolnovanie pamate [C] 16.05.2012 | 23:31
      Avatar Fridolín Pokorný Fedora 20  Používateľ
      1) Nie.
      2) Pamat sa uvolnuje, ak si ju skutocne alokujes (na halde). Je to komplementarna operacia k malloc()/calloc().

      Teraz ti nevypise core dump, pretoze volanie free() na NULL nevykona ziadnu operaciu podla normy. Dostal si len po prstoch. ;)
      • Re: Uvolnovanie pamate [C] 17.05.2012 | 00:07
        Maco   Návštevník
        Takze ked zavolam free(retazec) a program skonci chybne, znamena to, ze pamat nebola alokovana? Program igonruje moj malloc, alebo ho chybne vykona?

        * ano strlen(retazec) ↓

        Tomuto velmi nerozumiem. Dealokujes ukazatel, ktory ukazuje niekam na koniec kopirovaneho "retazec_1".
        • Re: Uvolnovanie pamate [C] 17.05.2012 | 00:12
          Avatar Fridolín Pokorný Fedora 20  Používateľ
          Tomuto velmi nerozumiem.
          > Dealokujes ukazatel, ktory ukazuje niekam na koniec kopirovaneho "retazec_1".


          Vsimni si, ze ukazatel retazec_1 menis - pri volani free() neukazuje na zaciatok miesta, ktore bolo pridelene pomocou malloc().
    • Re: Uvolnovanie pamate [C] 16.05.2012 | 23:38
      Avatar Fridolín Pokorný Fedora 20  Používateľ
      Mimochodom:

      1)
      sizeof(*retazec_1) == 1
      skor si myslel strlen(retazec_1)

      2) Dealokujes ukazatel, ktory ukazuje niekam na koniec kopirovaneho "retazec_1".

      • Re: Uvolnovanie pamate [C] 17.05.2012 | 03:05
        miso   Návštevník
        The strlen() function calculates the length of the string s, excluding the terminating null byte ('\0').
  • Re: Uvolnovanie pamate [C] 17.05.2012 | 00:07
    Avatar m4jkl   Používateľ
    tvoj problem je toto: while(*retazec++ != '\0')

    tym ten pointer menis.
    char * retazec_1 = "linuxos";
    char * retazec;
    char * retazec_zaloha;
    
    int main()
    {
        funkcia1();
       
        while(*retazec++ != '\0')
           {
           // ...........
           }
       
       funkcia2();
       return 0;
    }
    
    void funkcia1()
    {
        retazec = (char *)malloc(sizeof(char)*sizeof(*retazec_1)); 
        strcpy(retazec,retazec_1);
        retazec_zaloha = retazec;
    }
    
    void funkcia2()
    {
      free(retazec_zaloha);
    }
    
    • Re: Uvolnovanie pamate [C] 17.05.2012 | 00:16
      Maco   Návštevník
      Aha, dakujem. Tymto si mi velmi pomohol.