[ Nibble @ 17.06.2006. 17:00 ] @
Pomoc oko delociranja memorije

Pravim evo irc client i odmah na pocetku problemi.Da li je potrebno delocirati memoriju koju sam
alocirao sa malloc?Pokusavam da delociram ali se javljaju greske i program puca.
Pejstovo sam samo kljucni dio.

Code:

// part sam deklarisao kao char *part[128]; 

 while(1) //l00p 4ever :)
 {
  memset(buffer,0,256);
  valid=frecv(sock,buffer,sizeof buffer,0);
  z = 0; //ovo je int
  x = 0; //kao i ovo
  
//  if (valid<=0) break;
  printf("%s\n",buffer);

  for(i = 0;i < sizeof (buffer);i++)
  {
    if(buffer[i] == ' ' || buffer[i] == '\n' || buffer[i] == '\r')
    {
      if((i++ - z) < 127)
      {
        part[x]  = malloc((i-z) * sizeof(char));
        
        fstrcpyn(part[x],&buffer[z],i-z);

        if(part[x][0] == ':')part[x]++;
        
        fstrcpy(who,part[0]);
        z = i;
        x++;
      }
            }
        }
    }


//for(i = 0;i < x;i++) //
//free(part[x]);       //Zbog ovog dijela dodje do pucanja programa
[ z@re @ 17.06.2006. 19:42 ] @
Uvijek moras dealocirat memoriju. Sve bi trebalo bit u redu sa free(); rutinom na dnu koda, i ostalo mi se cini prilicno u redu, dio sa alociranjem i kopiranjem znakova. Moguce je jedino

Code:

if(part[x][0] == ':')part[x]++;


da radi ovog rucnog ikrementiranja u iducoj iteraciji petlje jedan u nizu blokova ostane nealociran, pa ce naravno na dealokaciji puknut program kad dodje do njega. Mozda je ovo i OK, nemam sad bas vremena izanalizirat ovaj kod, ali mi se ovo cini kao jedini potencijalni problem.
[ n1tr0 @ 17.06.2006. 20:12 ] @
Nisam bas obracao paznju na code, ali mi je odmah to dole sta si napisao zapalo u oko. Zar ne bi trebalo umesto x da stoji i:
Code:

for(i=0;i<x;i++)
free(part[i]); 

Do pucanja dolazi jer polusavas osloboditi memoriju koju si malopre oslobodio pa je samim tim i slobodna.
Ovde ti i oznacava niza part, dok ti je gore islo x kao clan niza, pa te verovatno to zbunilo...
[ Nibble @ 17.06.2006. 22:23 ] @
da da upravu si brate i sad sve fercera :).Hvala za ispravku.
[ Nibble @ 18.06.2006. 17:26 ] @
Opet ja i opet problemi.Ista greska isto sve.

Code:


//Sada sam part deklarisao kao **part

while(1)
{
y=0;
z=0;
j=0;

memset(buffer,0,512);

valid=frecv(sock,buffer,sizeof(buffer),0); //smjestam u buffer primljene podatke od servera

printf("%s<-|\n",buffer); //ispisujem

if(valid<=0)break; //ako nije uredu prekini

for(i=0;i<valid;i++) //slovo po slovo pregledanje
{
if(buffer[i]==' '|| //provjera karaktera
buffer[i]=='\r'  ||
buffer[i]=='\n'   )
{
y++; 
fstrcpyn(command,&buffer[z],i-z+2); //kopiraj u char command[256]

part=NULL;
part=(char*)realloc(part,y*sizeof(char)); //alociraj bajt vise nego prosli put 
part[j]=(char*)malloc((strlen(command)+1)*sizeof(char)); //napravi kolonu
    
strcpy(part[j],command); //kopiraj je

printf("part[%d]-%s\n",j,part[j]); //isprintaj

z=i; //z = pozicija gdje je nadjen karakter
j++; // 
}
}

//for(i=0;i<j-1;i++)free(part[i]); 
//oslobodi citavu matricu i 
//ovdje dodje do greske kad ovo stavim u kod 

free(part); //oslobodi i ovo radi

}

Evo slikice
[ Mali Misha @ 18.06.2006. 18:00 ] @
Citat:
part=(char*)realloc(part,y*sizeof(char));

Nije li part sa dve zvezdice?
Mlsim da bi ti i strdup bio od pomoci.

Kako bi bilo da postujes ceo kod kao attachment pa da ti neko popravi sta treba?
[ Nibble @ 18.06.2006. 19:18 ] @
Uredu evo kod.Nemogu koristiti strdup posto mogu koristiti samo API funkcije.Mislis da ne bi bilo lakse parsovati string sa strtok :) i postaviti to u part?
[ Mali Misha @ 18.06.2006. 22:23 ] @
Ok. Mislim da sam te razumeo. Ja bih ovo lično uradio sa listom, ali ako to ostavim po strani...

- Znači na početku imaš brojače j = 0; i z = 0;
- Mislim da nema potrebe za memset(buffer,0,512); jer ćeš dužinu stringa dobiti po izvršavanju recv, pa lako možeš da upišeš NULL na kraj ako je potrebno.

- Koliko vidim, nakon toga sledi jedan for sa brojačem i u kome deliš dobijeni string na reči, i koji ima jedan if, koji kontroliše praznine. Ovde bi bila mogića upotreba isspace(buffer[ i ]), ali to je manje bitno.

- Unutar for koristiš j i z za beleženje pozicija početka reči i mesta na kome se prethodno stalo. Možda nije najsrećnije ukoliko se traže tačno kraj i početak reči.

- Recimo da fstrcpyn(command,&buffer[z],i-z+2); radi šta treba. (ne preuzimam odgovornost)
- Nakon toga si imao jedan part = NULL, što bi potpuno odseklo sve što je part nosio pre toga, znači briši. Njemu sledi proširivanje part za jednu ćeliju part = (char**)realloc(part,(j+1) * sizeof(char*));.
- Na to mesto se prepisuje najnovija reč:

part[j] = (char*)malloc((strlen(command)+1) * sizeof(char));
strcpy(part[j],command);


- Beleženje nove završne pozicije sa z = i; i uvećavanje broja reči u part za jedan sa j++;.

To bi trebalo da radi. Pri oslobađanju bi trebalo prvo obrisati unete linije sa

Code:
for(i=0;i<j;i++)
{
  free( part[i] );
}


a potom i sam koren sa free(part);

Baci pogled na primer.
[ Nibble @ 18.06.2006. 22:54 ] @
To sam memset sam koristio da mi je lakse procitati sta server posalje.
Hvala ti Mishko od srca sto si izdvojio vrijeme da mi pomognes i sve radi ko ludo.