ze5400 Skrevet 9. juni 2008 Del Skrevet 9. juni 2008 (endret) Hei, Jeg er fersk på C. Ser på det en gang inni blandt, og idag tenkte jeg å se litt på allokering av minne. Skrev derfor en liten kode som allokerer minne som jeg lagrer "Test" i, deretter skal jeg realokkere minnet og legge til test 1000 ganger. int i; char* AllocTest; AllocTest = malloc(4); strcpy(AllocTest, "Test"); for(i = 1; i <= 1000; i++) { AllocTest = realloc(AllocTest, (i * 4)); strcat(AllocTest, "Test"); } printf("%s", AllocTest); free(AllocTest); Noen som kan forklare meg hvorfor den gir dette resultatet? Endret 9. juni 2008 av ze5400 Lenke til kommentar
GeirGrusom Skrevet 9. juni 2008 Del Skrevet 9. juni 2008 (endret) C strings er null terminert, så du må allokere 5 byte for å lagre 4 bokstaver. edit: litt bedre oppklaring Dersom du allokerer 4 byte, og den siste tegnet ikke er en null, vil strcat lete etter neste null, og begynne derfra. Derfor får du alle de rare tegna midt i stringen din. Endret 9. juni 2008 av GeirGrusom Lenke til kommentar
ze5400 Skrevet 9. juni 2008 Forfatter Del Skrevet 9. juni 2008 (endret) Nullterminering glemte jeg helt ja, men det fikser ikke problemet å erstatte firetallene med 5 .... Det virker når jeg erstatter de med 9. Hvorfor? "TestTest\ 0" ?? Endret 9. juni 2008 av ze5400 Lenke til kommentar
Mr.Garibaldi Skrevet 9. juni 2008 Del Skrevet 9. juni 2008 (endret) Se posten til GeirGrusom, han har den korrekte måten å løse det på... Endret 9. juni 2008 av Mr.Garibaldi Lenke til kommentar
ze5400 Skrevet 9. juni 2008 Forfatter Del Skrevet 9. juni 2008 Om jeg skriver nullterminering som \\ eller \ 0 er da det samme? (Av en eller annen grunn liker ikke forumet \ og 0 sammen) Lenke til kommentar
GeirGrusom Skrevet 9. juni 2008 Del Skrevet 9. juni 2008 Du missforstår litt Du trenger ikke en 0 etter hver "test" så det hjelper ikke å bytte ut alle firetall med 5-tall Bytt ut den opprinnelige allokeringen med 4, så du får plass til null terminering. int size = 5; char* test = (char*)malloc(size); test[0] = 0; // Stringen må starte tom strcpy(test, "test"); for(int i = 1; i <= 100; i++) { test = (char*)realloc(test, size + i * 4); strcat(test, "test"); } std::cout << test; free(test); Utestet, men tror dette skal være riktig. Husk at et minneområdes data er udefinert i utgangspunktet, så du bør alltid sette ting til f.eks. 0 før de brukes. Lenke til kommentar
ze5400 Skrevet 9. juni 2008 Forfatter Del Skrevet 9. juni 2008 (endret) Takk skal du ha Burde kansje ikke begynt på dette med hueverk Uansett, takk for hjelpa, etter å ha kikka på din kode fikk jeg det til å virke Men hvorfor caster du når du allokerer? Endret 9. juni 2008 av ze5400 Lenke til kommentar
Jaffe Skrevet 9. juni 2008 Del Skrevet 9. juni 2008 Det er vel fordi malloc returnerer ein void-peikar og du vil tilordne denne til ein char-peikarvariabel. Lenke til kommentar
shakur Skrevet 9. juni 2008 Del Skrevet 9. juni 2008 Det er vel fordi malloc returnerer ein void-peikar og du vil tilordne denne til ein char-peikarvariabel. Dette er ikke nødvendig i C, men i C++ vil compileren bli gretten hvis du ikke typecaster malloc. Lenke til kommentar
Emancipate Skrevet 9. juni 2008 Del Skrevet 9. juni 2008 Det er vel fordi malloc returnerer ein void-peikar og du vil tilordne denne til ein char-peikarvariabel. Dette er ikke nødvendig i C, men i C++ vil compileren bli gretten hvis du ikke typecaster malloc. Beklager hvis jeg kaprer tråden, men er ikke hele poenget med void * at du skal kunne bruke den uten casting? Kan noen forklare meg hva den godeste Hr. Stroustrup har tenkt her? Det virker jo høl i hue. Argumentet om typesikkerhet gjelder ikke, ettersom void * kan castes til hva som helst, og da forsvinner jo typesikkerheten. Ikke bare kan den castes til hva som helst, den MÅ kastes. Man tvinges jo til "dårlig praksis"-koding. Lenke til kommentar
GeirGrusom Skrevet 9. juni 2008 Del Skrevet 9. juni 2008 Jeg er enig. En får ingen typesikkerhet å eksplisitt caste fra void* fordi den MÅ uansett castes til et eller annet, en kan ikke bruke en void* til noe. Så hvorfor skal compileren blande seg? dette fører egentlig bare til mindre kompatibilitet med gammel C kode, og har ingen fordeler for programmereren. Lenke til kommentar
Emancipate Skrevet 10. juni 2008 Del Skrevet 10. juni 2008 Jeg er enig.Bra. Jeg var redd jeg hadde misforstått noe. Lenke til kommentar
Dead_Rabbit Skrevet 12. juni 2008 Del Skrevet 12. juni 2008 Poenget med void-pekere er vel at man skal kunne peke til noe man ikke vet hva er -- ikke at det skal være en slags universal/dynamisk type? En void-peker lar deg peke til et sted i minnet, men for å kunne bruke det på en fornuftig måte, må det nødvendigvis castes. En mulig grunn til at C++ krever at du eksplisitt caster void-pekere, kan vel kanskje være at "random bruk av void-pekere" har ført til en del misforståelser...? Lenke til kommentar
GeirGrusom Skrevet 12. juni 2008 Del Skrevet 12. juni 2008 int* ptr = malloc(1024); Det er ingen tvil over hva programmereren er interessert i, men i C++ må en gjennom omveien å caste først int* ptr = (int*)malloc(1024); Denne castingen gjør ingenting! Den gjør ikke koden mer tydelig, den oppfordrer ikke til god programmeringsskikk og den endrer heller ikke den endelige maskinkoden som blir skrevet. Så hva er egentlig poenget med eksplisit cast av void? Jeg fatter det ikke, eneste som skjer er at gammel C kode trenger mer arbeid før den kan kompileres i en C++ compiler. Lenke til kommentar
Giddion Skrevet 12. juni 2008 Del Skrevet 12. juni 2008 Poenget er vel at du gjør en handling som du da forhåpentligvis vet konsekvensen av. Dette skal hindre deg i å gjøre dumme ting som igjen skal gjøre programmet mer stabilt. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå