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 21  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 21  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 21  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 | 10:19
            Avatar Fridolín Pokorný Fedora 21  Používateľ
            Pridaj +1 samozrejme.
          • Re: Uvolnovanie pamate [C] 17.05.2012 | 10:22
            Avatar Fridolín Pokorný Fedora 21  Používateľ
            Inym riesenim:
            char retazec_1[] = "linuxos";
            
            potom:
            sizeof(retazec_1)
            je ok.
    • 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.