Avatar
mnauik
Člen
Avatar
mnauik:

Mam problem, tento calloc, pri poradi==4 delkaRetezce==3

seznamStringu[po­radi] = (char**)calloc(del­kaRetezce,size­of(char*));

meni tyto chary:
seznamStringu[po­radi][0]
seznamStringu[po­radi][1]
seznamStringu[po­radi][2]

nebo-li mam seznam stringu, alokuju callocem pro 5. string, ktery chci tam chci pridat, ale pri calloc se nesmyslne zmeni chary v 1. retezci - tedy misto abc mam ruzne otazniky a nesmyslne znaky. Prosel jsem to debuggerem a tato situace nastane za podminek, ktere jsem jiz napsal poradi==4, delkaRetezce==3

Odpovědět 1.6.2014 22:08
minusuj mě, ale zdůvodni to ;)
Avatar
coells
Redaktor
Avatar
Odpovídá na mnauik
coells:

:-D viz komentáře v kódu

// 1) alokujes POLE POINTERU NA CHAR
// pokud je delkaRetezce = 3, pak alokujes 24 bytu
// 2) nastavíš 4. pointer v poli seznamStringu na nove alokovanou pamet
// (pokud poradi = 4)
seznamStringu[poradi] = (char**)calloc(delkaRetezce,sizeof(char*));

// protoze jsi nastavit hodnotu pointeru seznamStringu[poradi] na calloc
// mas tam ted NULL
// pres nasledujici prikazy se divas na adresu 0 ve svem datovem segmentu
// proto ty otazniky
seznamStringu[poradi][0]
seznamStringu[poradi][1]
seznamStringu[poradi][2]

Takže calloc nic nemění - ani nemůže - alokuje pamět a nastaví hodnoty na 0.
Hodnotu proměnné si měníš sám, a protože se jedná o pointer a ten pointer je nulový, máš velký problém ;-)

 
Nahoru Odpovědět  +1 1.6.2014 22:18
Avatar
mnauik
Člen
Avatar
Odpovídá na coells
mnauik:

ja to napsal spatne, omlouvam se, meni tyto chary:

seznamStringu[0][0]
seznamStringu[0][1]
seznamStringu[0][2]

neboli prvni "retezec"

Nahoru Odpovědět 1.6.2014 22:26
minusuj mě, ale zdůvodni to ;)
Avatar
Posix
Člen
Avatar
Odpovídá na mnauik
Posix:

jak už říkal coels... pleteš si char a char* a není ani jisté, jestli víš, co dělá calloc. Celé se mi to nezdá. Kdybys hodil větší kus kódu, tak bysme ti mohli líp poradit.

Nahoru Odpovědět 1.6.2014 22:34
Proč to dělat jednoduše, když to jde složitě.
Avatar
mnauik
Člen
Avatar
mnauik:

Zadani je takove, ze se programu zada string nejake delky (ale max. 8 ) a program vypise vsechny permutace, ktere budou serazene.

Algoritmus ohledne permutaci jsem bral odtud:
http://www.geeksforgeeks.org/…iven-string/

A ja ho trochu pozmenil, aby vyhovoval zadani (nevypisu permutace hned, ale nejprv je dam do pole a pak je setridim)

void swap (char *x, char *y)
{
    char temp;
    temp = *x;
    *x = *y;
    *y = temp;
}


int k=0;

void permute(char *a, int i, int n)
{
   int j;
   if (i == n)  {

   seznamStringu[poradi] = calloc(delkaRetezce,sizeof(char*));
  strncpy(seznamStringu[poradi],a,delkaRetezce);

    poradi++;
   }
   else
   {
        for (j = i; j <= n; j++)
       {
          swap((a+i), (a+j));
          permute(a, i+1, n);
          swap((a+i), (a+j));
       }
   }
}

poradi - globalni promenna typu int, po kazdem zapsani retezce do pole se zvetsi o 1.

delkaRetezce - delka jednoho retezce

delkaPole - delka pole - neboli max pocet retezcu, ktere se vejdou do pole, jelikoz se jedna o permutace, tak je to delkaRetezce! (faktorial)

Editováno 1.6.2014 22:45
Nahoru Odpovědět 1.6.2014 22:44
minusuj mě, ale zdůvodni to ;)
Avatar
coells
Redaktor
Avatar
Odpovídá na mnauik
coells:

Jak alokuješ seznamStringu[] ? Není náhodou tahle proměnná neinicializovaná?

 
Nahoru Odpovědět 1.6.2014 22:52
Avatar
mnauik
Člen
Avatar
mnauik:

Jeste jsem nedodal main a v mainu inicializovana je:

int main()
{


int i = 0;      //cyklova prom
int j = 0;      //cyklova prom
char retezec[8];    //retezec vstupu
    scanf("%s",retezec);    //nacteni vstupu

//strcopy(retezec,tmp);


int    delka = strlen(retezec);     //prirazeni delky
delkaRetezce = delka;               //delka retezce globalne
delkaPole = fact(delka);            //delka pole globalne
//printf("delkaPole %i",delkaPole);

    seznamStringu=calloc(delkaPole,sizeof(char));      //alokace pole



    printf("Delka retezce: %i\n",delka);
    printf("Vstupni retezec: \"%s\"\n",retezec);
        for(i = 0; i < delka - 1; i++){                     //serazeni retezce
        for(j = 0; j < delka - i - 1; j++){
            if(retezec[j+1] < retezec[j]){
                int tmp = retezec[j + 1];
                retezec[j + 1] = retezec[j];
                retezec[j] = tmp;
            }
        }
    }



   permute(retezec, 0, delka-1);
   printf("%s\n",seznamStringu[0] );                       //permutace pole

   // qsort(seznamStringu,sizeof(seznamStringu)/sizeof(seznamStringu[0]),sizeof(seznamStringu[0]), strcmp);


   for(i=0;i<delkaPole;i++) {                           //vypis pole

        printf("%s\n",seznamStringu[i]);
   }

   return 0;
}

Pak tam mam jeste metodu fact - coz je rekurzivni faktorial.
edit: v C to vlastne neni metoda, ale funkce.

Editováno 1.6.2014 22:59
Nahoru Odpovědět 1.6.2014 22:58
minusuj mě, ale zdůvodni to ;)
Avatar
coells
Redaktor
Avatar
Odpovídá na mnauik
coells:
// alokuje fact(delka) bytu
seznamStringu=calloc(delkaPole,sizeof(char));

// alokuje fact(delka) pointeru na byte
seznamStringu=calloc(delkaPole,sizeof(char *));

Jinak řečeno, alokuješ 8x méně paměti, než potřebuješ.

 
Nahoru Odpovědět 1.6.2014 23:02
Avatar
mnauik
Člen
Avatar
Odpovídá na coells
mnauik:

Dekuji, je to tak.

Jak jeste seradim pole? Zkousel jsem:

qsort(seznamStringu,sizeof(seznamStringu)/sizeof(seznamStringu[0]),sizeof(seznamStringu[0]), strcmp);

ale nefunguje.

napr. kdyz vlozim permutaci aba tak do pole to vyhodi:
aab
aba
aab
aba
baa
baa

ale potrebuji to seradit, aby to bylo:
aab
aab
aba
aba
baa
baa

Nahoru Odpovědět 1.6.2014 23:12
minusuj mě, ale zdůvodni to ;)
Avatar
coells
Redaktor
Avatar
Odpovídá na mnauik
coells:
qsort(seznamStringu,delkaPole,sizeof(char*), strcmp);
 
Nahoru Odpovědět 1.6.2014 23:18
Avatar
mnauik
Člen
Avatar
Odpovídá na coells
mnauik:

nejak to nechce seradit (coz je divne, prave tenhle tvar qsort radí i jinde), nejak to prohodi ty retezce, ale netusim podle jakeho pravidla, napr misto prvnich 4 permutaci (retezec delky 4) ve tvaru:

aabb
aabb
aabb
aabb
........

to vypise:
aabb
baba
aabb
bbaa
........

Nahoru Odpovědět 1.6.2014 23:31
minusuj mě, ale zdůvodni to ;)
Avatar
coells
Redaktor
Avatar
Odpovídá na mnauik
coells:
int compare (const void *a, const void *b)
{
    const char **x = (const char **)a;
    const char **y = (const char **)b;
    return strcmp(*x, *y);
}

qsort(seznamStringu, delkaPole, sizeof(char *), compare);
 
Nahoru Odpovědět  +1 2.6.2014 10:25
Avatar
mnauik
Člen
Avatar
Odpovídá na coells
mnauik:

Dekuji moc, kontrolni system to vzal. Zkousel jsem pred tim bubblesort, ale to bylo na nej moc pomaly a vedel jsem o tom qsortu, ale nevedel jsem jak :)

Nahoru Odpovědět 2.6.2014 12:33
minusuj mě, ale zdůvodni to ;)
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 13 zpráv z 13.