Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  C linked listi viga märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
MarvinD
HV vaatleja

liitunud: 07.05.2006




sõnum 08.03.2010 21:05:11 C linked listi viga vasta tsitaadiga

Tegin harjutuslikel eesmärkidel ühe programmi jupi, mis moodustab struktuuridest niiöelda kolme realise linked listi ja täidab selle tähestiku tähtedega. Iga järgmine täht lisatakse listi lõppu. Probleem selles, et kompilaator vigu ei leia ja käima minnes jõuab sinna maani, kus if'i sees maatriks hakkab viitama esimesele märgile. Peale seda hangub.
Väljavõte funktsioonist ise:
SH **looStruktuur(int arv)
{
     int i ,j;
     SH **matrix = NULL, *uus =NULL, *last= NULL;
     matrix=(SH **)malloc(arv*sizeof(SH *));
     uus=(SH *)malloc(sizeof(SH));
     last=(SH *)malloc(sizeof(SH));
     for (i=0;i<arv;i++)
     {
         (*(matrix+i))=(SH *)malloc(sizeof(SH));
         (*(matrix+i))->sona=(char*)malloc(sizeof(char)+1);
         (*(matrix+i))->pNext=(SH*)malloc(sizeof(SH));
         (*(matrix+i))=NULL;
         for(j=0;j<7;j++)
         {
               uus->pNext=(SH *)malloc(sizeof(SH));
               uus->pNext=NULL;
               uus->sona=(char*)malloc(sizeof(char)+1);
               uus->sona=tahestik(j);
               if(!(*(matrix+i)))
               {
                    (*(matrix+i))->sona=tahestik(j);
                    (*(matrix+i))->pNext= NULL;
               }
               else
               {
                    for(last=(*(matrix+i)); last->pNext; last=last->pNext);
                    last->pNext=uus;
               }
         }
     }
     return (matrix);           
}


Äkki oskate öelda milles võiks viga olla või mida muuta.
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 08.03.2010 21:25:04 vasta tsitaadiga

c:
  1. SH **looStruktuur(int arv)
  2. {
  3.      int i ,j;
  4.      SH **matrix = NULL, *uus =NULL, *last= NULL;
  5.  
  6.      matrix=(SH **)malloc(arv*sizeof(SH *));
  7.      uus=(SH *)malloc(sizeof(SH));
  8.      last=(SH *)malloc(sizeof(SH));
  9.  
  10.      for (i=0;i<arv;i++)
  11.      {
  12.          (*(matrix+i))=(SH *)malloc(sizeof(SH));
  13.          (*(matrix+i))->sona=(char*)malloc(sizeof(char)+1);
  14.          (*(matrix+i))->pNext=(SH*)malloc(sizeof(SH));
  15.          (*(matrix+i))=NULL;
  16.          for(j=0;j<7;j++)
  17.          {
  18.                uus->pNext=(SH *)malloc(sizeof(SH));
  19.                uus->pNext=NULL;
  20.                uus->sona=(char*)malloc(sizeof(char)+1);
  21.                uus->sona=tahestik(j);
  22.                if(!(*(matrix+i)))
  23.                {
  24.                     (*(matrix+i))->sona=tahestik(j);
  25.                     (*(matrix+i))->pNext= NULL;
  26.                }
  27.                else
  28.                {
  29.                     for(last=(*(matrix+i)); last->pNext; last=last->pNext);
  30.                     last->pNext=uus;
  31.                }
  32.          }
  33.      }
  34.      return (matrix);           
  35. }


1. Sa paned real 14 (*(matrix+i)) võrduma NULL-ga millele sa real 12 mälu eraldasid. Põhimõtteliselt sa lekitad lisaks muudele probleemidele siin ka mälu
2. Miks sa pNext liikmele mälu eraldad?

NB1: matrix[i] on palju arusaadavam kui (*(matrix+i))
NB2: Too ära ka tahestik() funktsiooni ja SH andmetüübi definitsioonid.
NB3: Kasuta syntax tag-e koodi postitamisel!

_________________
ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn
Kommentaarid: 34 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
MarvinD
HV vaatleja

liitunud: 07.05.2006




sõnum 09.03.2010 15:51:52 vasta tsitaadiga

Tänud, nii palju oli kasu, et nüüd täidab maatriksit vähemalt, kuid läbimisel millegi pärast esimesele tähele viitab korralikult, teine täht on maatriksi viimane ja seda jääb kordama. Millegi pärast matrix[i]->pNext ei suuda järgmisele viidata. Kuid viimase tähe võtab küll kuskilt.
c:
  1. struct Header
  2. {
  3.       char *sona;
  4.       struct Header *pNext;
  5. };
  6.  
  7. typedef struct Header SH;
  8.  
  9. char *tahestik(int i)
  10. {
  11.      char *s;
  12.      s=(char*)malloc(sizeof(char)+1);
  13.      if (i==0)
  14.           strcpy(s,"A");
  15.      else if (i==1)
  16.           strcpy(s,"B");
  17.      else if (i==2)
  18.           strcpy(s,"C");
  19.      else if (i==3)
  20.           strcpy(s,"D");
  21.      else if (i==4)
  22.           strcpy(s,"E");
  23.      else if (i==5)
  24.           strcpy(s,"F");
  25.      else if (i==6)
  26.           strcpy(s,"G");
  27.      return (s);
  28. }
  29.  
  30. SH **looStruktuur(int arv)
  31. {
  32.      int i ,j;
  33.      SH **matrix=NULL, *uus =NULL, *last= NULL, *p=NULL;
  34.      matrix=(SH **)malloc(3*sizeof(SH *));
  35.      uus=(SH *)malloc(sizeof(SH));
  36.      last=(SH *)malloc(sizeof(SH));
  37.      for (i=0;i<3;i++)
  38.      {
  39.          matrix[i]=NULL;
  40.          for(j=0;j<7;j++)
  41.          {
  42.                if(!(matrix[i]))
  43.                {
  44.                    matrix[i]=(SH *)malloc(sizeof(SH));
  45.                    matrix[i]->sona=(char*)malloc(sizeof(char)+1);
  46.                    matrix[i]->sona=tahestik(j);
  47.                    printf("%s ",matrix[i]->sona);
  48.                    matrix[i]->pNext= NULL;
  49.                }
  50.                else
  51.                {   
  52.                    uus->sona=(char*)malloc(sizeof(char)+1);
  53.                    uus->sona=tahestik(j);
  54.                    uus->pNext=NULL;
  55.                    for(last=matrix[i]; last->pNext; last=last->pNext);
  56.                    last->pNext=uus;
  57.                    printf("%s ",uus->sona);
  58.                }
  59.                
  60.          }
  61.          printf("\n");
  62.      }                 
  63.      for (i=0; i<3; i++)
  64.      {
  65.          for (p=matrix[i], j=0; j<15 && p->pNext; j++, p=p->pNext)
  66.          /* j on lisatud, et tsükkel lõpetada, kuna p->pNext ei saa
  67.          kunagi millegi pärast NULL */
  68.          {
  69.              printf("%s ",p->sona);
  70.          }
  71.          printf("\n");
  72.      }
  73.      return(matrix);
  74. }
  75.  
  76. char *tahestik(int i);
  77. SH **looStruktuur(int arv);


Sain jagu, olin kogemata struct uue mälu eraldamise pannud koodi algusesse mitte tsüklisse ja printimisel for tsüklis tuli lõpetada kui p=NULL mitte p->pNext.
Üks küsimus on muidu veel jäänud, et kui ma võtan kasutusele uue viida *p, mis hakkab osutuma mingile olemas olevale struktuurile, siis kas pean talle eraldi mälu eraldama, või antakse see juba deklareerimisel SH *P
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 11.03.2010 13:48:54 vasta tsitaadiga

Real 55 olevat for tsüklit ei täideta kuna matrix[i]->pNext on alati sul NULL. Real 46 on sul mäluleke - real 45 eraldatud mälu läheb kaotsi .
Lisaks on ausaltöeldes arusaamatu mis seal listis peaks olema.. tee joonis või tabel sellest mida saavutada tahad.

malloc(sizeof(char)+1) - see on samuti kahtlane, selgem oleks malloc(sizeof(char) * 2) kuna sa soovid eraldada 2 baiti mälu - 1 tähemärgi jaoks ning teine stringi terminaatoorile. Olugugi, et sizeof(char)+1 == sizeof(char)*2 enamikel arhidektuuridel, on see natuke praktika.

Loomulikult ei oleks sul tähestiku hoidmiseks vaja stringi ja selle jaoks mälu eraldada - kasutada võiks lihtsalt üht char muutujat, mis hoiab ühe tähemärgi ASCII koodi.

_________________
ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn
Kommentaarid: 34 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
Urmet
HV vaatleja

liitunud: 29.07.2005




sõnum 11.03.2010 15:55:58 vasta tsitaadiga

troglodyte kirjutas:
Olugugi, et sizeof(char)+1 == sizeof(char)*2 enamikel arhitektuuridel, on see natuke praktika.
Koodi jooksutav masin ei loe antud juhul midagi, sest niikaua, kui kasutatavat keelt saab mingilgi määral C'ks kutsuda, on standardis paika pandud, et sizeof(char) == 1
Kommentaarid: 10 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 10
tagasi üles
vaata kasutaja infot saada privaatsõnum
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 12.03.2010 20:16:27 vasta tsitaadiga

Jah, sul on selles suhtest täielikult õigus.
_________________
ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn
Kommentaarid: 34 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 34
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
MarvinD
HV vaatleja

liitunud: 07.05.2006




sõnum 14.03.2010 23:08:43 vasta tsitaadiga

Real 55 fori esimesel korral ei täidetagi, mis peabki nii olema, sest tegemist on sel juhul teise liikmega listis. Järgmisel korral täidetakse üks kord jne, ehk liigutakse listi viimase kirjeni ja pannakse selle pNext viitama uuele strutkuurile. Seda matrix[i]-pNext=NULL if korral täidetakse sel juhul ju, kui matrix[i] ei eksisteeri, mis on alati esimesel korral.

Listi täitsin tähtedega, et oleks lihtsam aru saada sellest pNext viida töötsükli põhimõttest. Tööle lastes oli lihtne jälgida tulemust.
Output:
A B C D E F G
A B C D E F G
A B C D E F G

Seda ma tean, et need mallocid on võrdsed, lihtsalt koolist on külge jäänud.

Tänud, ma ei märganudki, et real 46 on viga. Ei tulnud selle peale et = ei teinud koopiat vaid hakkab samasse kohta viitama, kus see funktsiooni väljund on. Mõistlik oleks vast kasutada selle asemel seal strcpy.

Kas c's ei ole mingit käsku, millega saaks ASCII'st tagasi täheks muuta? Mille korral ma ei peaks kasutama seda tahestik() funktsiooni tähe saamiseks numbrist.
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  C linked listi viga
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.