Allokere structures og pointers

Tags:    c++

<< < 12 > >>
Jeg er i gang med at lave et mini bibliotek til at læse bmp filer med i C. Jeg har 2 problemer. Den ene er hvordan allokerer jeg en structure ved brug af malloc/calloc uden at bruge explicit casting som nævnes bør undgås her: http://en.wikipedia.org/wiki/Calloc#Casting_and_type_safety
Den anden er at nogle af mine pointers på mystisk vis peger på NULL.

Min kode er som følger:
Fold kodeboks ind/udKode 

Der er et billede det pågældende sted og jeg kan se at i f.eks. selve magic strukturen bliver magic sat til noget gyldigt tekst og tror at det er ved bmp_readFile at pointeren til denne struktur ikke bliver sat ordentligt. Jeg får ingen af de fejlbeskeder der er mulige så jeg lidt på bar bund.

På forhånd tak for hjælpen.



Hvis du skriver rigtigt C kode (dvs. ikke C++) er der ingen grund til at have de der cast, nogen vil endda sige at de gør mere skade en gavn.

Hvis du skriver C++ kode, og af en eller anden grund vil bruge malloc/calloc er du nødt til at leve med de der cast.

Husk at når du har en pointer inden i en struct, skal du allokere hukommelse til denne pointer separat.

I øvrigt tror jeg at bmp_magic skal være to chars, ikke to pointer til char.

Der findes en struct der svarer til din bmp_header, som kan læses med én fread.



Hvis du skriver rigtigt C kode (dvs. ikke C++) er der ingen grund til at have de der cast, nogen vil endda sige at de gør mere skade en gavn.

Hvis jeg fjerner casting får jeg: Error: a value of type "void *" cannot be used to initialize an entity of type "STRUCTURENAVN *"


Husk at når du har en pointer inden i en struct, skal du allokere hukommelse til denne pointer separat.

Hvordan skal det forstås. Jeg har prøvet at ændre min bmp_readFile() funktion til dette og det løser ikke problemet (altså lave pointeren med calloc):
Fold kodeboks ind/udKode 


Der findes en struct der svarer til din bmp_header, som kan læses med én fread.

Du mener at jeg kunne læse de antal bytes min header struktur fylder ind som en header og så vil det være korrekt så længe min strukturs elementer har den korrekte rækkefølge? Men der er jo det problem at compileren laver om på rækkefølgen/størrelsen?



Indlæg senest redigeret d. 11.06.2010 20:37 af Bruger #14645
Den første fejl tyder på at du oversætter det som C++ og ikke som C

Du skal
struct bmp_magic* pMagic = (struct bmp_magic*)calloc(1, sizeof(struct bmp_magic));
pMagic->magic[0] = calloc(1, 1234);
pMagic->magic[1] = calloc(1, 4321);
Husk også at free de to pointere inde i pMagic


Men som nævnt skal du lave strukturen om, til:
struct bmp_magic {
unsigned char magic[2];
};

OG så skal du kun have en malloc/calloc



Jeg har nu næsten fået det hele til at virke. Jeg fjernede explicit casting og fik dermed rød tekst under. Men den kunne godt compile alligevel. Har et problem med magic strengen og data. Når jeg læser noget selv hvis jeg læser 0 bytes så bliver tekststrengen "ýýýý««««««««îþîþ" sat på til sidst. Jeg ved ikke hvorfor dette sker. Der er også problem med at free magic strengen men jeg det hænger sammen med den ekstra streng måske.

Fold kodeboks ind/udKode 




Du skal ikke have denne linje:
*pMagic->magic = calloc(2, sizeof(unsigned char));

Men ellers læser den magic til BM som den skal, jeg har ikke checket om resten virker.



Du skal ikke have denne linje:
*pMagic->magic = calloc(2, sizeof(unsigned char));

Nej kan jeg godt se nu, jeg laver jo en hel struktur alligevel så dette element er jo helt nyt.

Tror jeg har løst problemet/årsagen. Debuggeren ignorerer de størrelsesbegrænsninger der er på variablerne. F.eks. magic strengen på en BMP er typisk "BM" den ignorerer så begrænsningen i at den kun må være 2 elementer og læser videre i hukommelsen indtil den tilfældigt rammer et '\0'. Jeg prøve de at forlænge størrelsen af arrayet med én og sætte den sidste til '\0' og så stoppede de tilfældige tegn der kommer bagved i debuggeren.

Mange tak for hjælpen Bertel :D



Kom til at "svare" i nedenstående.



Indlæg senest redigeret d. 12.06.2010 17:50 af Bruger #14645
Hmm er lidt bekymret over at hukommelsen ikke bliver frigjort.

Har en macro:
Fold kodeboks ind/udKode 


bmp_file er en struktur med allokerede pointere:
Fold kodeboks ind/udKode 


Jeg frigører sådan en struktur med:
Fold kodeboks ind/udKode 


Jeg har denne her main hvor jeg laver 5000 af disse strukturer:
Fold kodeboks ind/udKode 


Før den har allokeret alle n strukturer bruger programmet:
Ved n=100
Start: 348KB
Efter allokering: 1256KB
Efter frigørelse: 1256KB

Ved n=500
Start: 348KB
Efter allokering: 4104KB
Efter frigørelse: 2460KB

Ved n=1000
Start: 352KB
Efter allokering: 7704KB
Efter frigørelse: 2484KB

Ved n=5000
Start: 372KB
Efter allokering: 35576KB
Efter frigørelse: 4412KB

Hvorfor kan det være at den svinger sådan?? Og alle tallene kan svinge med et par kilobytes forskellig ved hver kørsel?

Her er hele koden hvis den ønskes set:
Fold kodeboks ind/udKode 




Indlæg senest redigeret d. 12.06.2010 17:47 af Bruger #14645
Jeg kan ikke se at der er noget galt med koden. Hvordan har du fundet de tal for hukommelsesforbrug? Du kan ikke være sikker på at programmet giver hukommelsen tilbage til OS'et med det samme. I "gamle" DOS dage gav et program aldrig hukommelse tilbage til DOS, når det først havde fået den.

Lige et par bemærkninger:
1: Der er ingen grund til at bruge din macro __FREE_NOT_NULL, free checker selv om pointeren er NULL.

2: Man har normalt ikke ; efter den sidste } i funktioner, de virker forvirrende.

3: sizeof(char), sizeof(uint8_t) og sizeof(unsigned char) er altid 1.



Jeg kan ikke se at der er noget galt med koden. Hvordan har du fundet de tal for hukommelsesforbrug? Du kan ikke være sikker på at programmet giver hukommelsen tilbage til OS'et med det samme. I "gamle" DOS dage gav et program aldrig hukommelse tilbage til DOS, når det først havde fået den.

Jeg bruger joblisten i windows (taskmgr.exe). Virker da bare lidt pudsigt at det altid er det samme som der er til overs. Er C ikke så low level at hvis jeg siger frigør så når det kald ned til OS'et som så frigører hukommelsen? Der vel ingen garbage collector at tage i betragtning :S.

Så vil du tro at programmet fungerer korrekt (til den grad man kan være sikker)?



<< < 12 > >>
t