Gå til innhold

C og allokering - Rare resultater [LØST]


Anbefalte innlegg

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?

 

post-61812-1213001221_thumb.jpg

Endret av ze5400
Lenke til kommentar
Videoannonse
Annonse

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 av GeirGrusom
Lenke til kommentar

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
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

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

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

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

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...