Det giver fx ikke en segmentation fault når jeg udelader malloc i dette eksempel:
int main(void) { int **ip; ip[2] = NULL; return 0; }
Her sætter jeg også en pointer til en pointer til NULL uden at have brugt malloc først, og der kommer ikke nogen segmentation fault. Det gør der derimod i mit oprindelige eksempel.
I begge tilfælde bruger du en uinitialiseret pointer. Muligvis peger den på noget RAM du må pille i, og så får du umiddelbart ingen fejl (men det er en fejl, for du ændrer på noget du ikke ved hvad er), eller også peger den udenfor den RAM du må pille i, og så får du en rigtig fejl med det samme.
Og så lige: hvis du vil bruge kids som et array, så skal du huske at allokere så mange pladser, som du for brug for. Skal du bruge kids[0] til kids[9], så
np->kids=malloc(10*sizeof(node_t*))
Du får næppe umiddelbart en fejl hvis du så bruger kids[10], men du ændrer i noget, der kan overraske dig senere.
Alt dette bøvl kan så nemt laves forkert af en programmør, og kan være svært at opdage ved tests, og svært at rette, at C-programmer ofte er "ustabile". Man gik et skridt videre med Java, hvor det ganske enkelt ikke kan lade sig gøre at lave denne slags fejl, uden at blive gjort opmærksom på det.
Men du må ikke tilgå det ip peger på. dvs: *ip = 123;
Dette er ikke så smart: int *ip; ip = malloc(sizeof(int)); ip = NULL;
Du sætter ip til at pege på dynamisk allokeret plads, og der på til at pege på null, derved har du glemt adressen på det du allokerer, og har ikke vundet noget.
Her sætter du ip til at pege på noget (tre forskellige ting): int *ip; ip = malloc(123*sizeof(int)); ip = NULL; int i; ip = &i;
Her ændrer du det ip peger på: *ip = 123;
For at man kan det skal ip pege på noget gyldigt, og ikke NULL.
ok nu er jeg forvirret. Prøver lige med et lidt andet eksempel:
typedef struct test{ int x;
}test;
int main(void) { // TILLADT test *tp; tp = NULL;
// IKKE-TILLADT test **tp; tp[0] = NULL;
return 0; }
Det vil altså sige at så længe man kun brugere "normale" pointere behøver man ikke malloc. Men når man bruger pointere til pointere så skal man bruge malloc.
Reglen er simpel: en pointer skal pege på noget hvis du bruger den med *p eller p-> Hvis du ikke bruger den på den måde kan du selvfølgelig sætte den til NULL.
Du kan bruge malloc, eller sætte pointeren til at pege på det samme som en anden pointer peger på (som en gang tidligere er lavet med malloc)
Dette giver en segmentation fault. Det mærkelige er at hvis jeg bare udkommentere enten test 1 eller test2 så forsvinder den (lige meget hvilken bare så længe én af dem er udkommenteret)!
Dvs at jeg i teorien ikke kan vide om det er test1 eller test2 der skyld i fejlen.
På baggrund at dette indlæg må det være test1 der er årsag til fejlen. Men hvis jeg bare udkommentere test2 så er alt fint. Det er skisme sort!
Jeg ser ingen malloc i test1. Da den så peger på noget udefineret kan det være indenfor lovlig RAM hvis test2 ikke er med. Det er sådan set fuldstændig ligemeget, for du har en uinitialiseret pointer.
Er godt klar over at "a" i test1 ikke peger et gyldigt sted (mangler malloc) men det er netop det som er ideen for at fremprovokere fejlen. Det er bare pænt sort at den kun opstår hvis jeg samtidig laver test2. C virker som IT verdens svar på bungie jump med varierende elastik længde.
I C++ kan man bruge std containere (vector, list, map, string, etc) til at løse mange af de problemer med pointere og dynamisk hukommelses allokering der er i C
Dermed er C++ et facelift til C.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.