16. oktober 2002 - 20:00Der er
31 kommentarer og 1 løsning
Problem med oprettelse af array
Jeg har et program, som eksekveres uden problemer i Win98 men afsluttes pludseligt i XP/2000. Jeg har fundet frem til at problemet har noget at gøre med denne linie, hvor jeg opretter et char-array:
char *model = new char[32];
I Win98 er der overhovedet ingen problemer, men i XP/2000 afsluttes programmet pludseligt lige inden/efter denne linie. Er der nogen, som har en forklaring/løsning på dette. Det sker også af og til at programmet laver en exception (stadig kun i XP/2000).
jeg tror du får fejlen fordi du opretter et char array dynamisk (char *ret = new char[64];) inde i metoden og returnerer dette (ret går ud af scope).
Var det ikke bedre at lave call-by-reference, altså: char *RAM::afgiv(char *ret) { #ifdef DEBUG_ON printf("RAM::afgiv()\n"); #endif // char *ret = new char[64]; ret[0] = 0; //beregn antal MB ram rundet op til nærmeste 4 MB double total = m.dwTotalPhys; total = ceil(total/(1048576*4))*4; sprintf(ret,"hardware=[%d#%d#[[%d#'%.f MB']]]",kode,0,0,total); // return ret; }
Jeg forstår ikke at du bruger en double til at holde antallet af MB i. En long ville da være mere passende, da ceil returnerer et heltal...
Og jeg kan ikke se den førstnævnte linie i den kode, du har sendt...
En yderligere kommentar omkring brugen af print-sætninger til debugging er, at det ikke nødvendigvis er på det tidspunkt, programmet går ned, at fejlen opstår. Din fejl kan være en vildfaren pointer, der på et ret sent tidspunkt bliver benyttet med terminering til følge. Er der ikke nogen returkode eller fejlmeddelelse? Laver du exceptionhåndtering?
Søren: det kan vel være ligemeget når man netop siger new. Debug: du bør prøve 2 ting: afsætte mere plads fx 128 tegn og teste for om den overhovedet blev oprettet: if (ret==null) { printf("Nix"); }
erik> det har du jo nok ret i. men det giver ikke ligefrem overblik at gøre det i metoden. det kan jo være svært at vide hvornår en variabel er oprettet med new og hvornår den ikke er - hvordan skal man da kunne holde styr på det :-)
"Memoryleaks" - bare ordet bringer tanken tilbage til hyggelige stunder ved computeren på jagt efter fejlen. Jeg fik lavet et godt værktøj til "gammeldags" C. En makro redefinerede malloc, realloc og free, således at de - i en testudgave - skrev adresserne ud på en fil, og efter programmet var kørt kunne et simpelt Perl script løbe filen igennem og se om der var fejl. Det var der jo så af og til. Senere opdager man så at andre har lavet meget smartere løsninger .. :)
til erikjacobsen: Pladsen er uden tvivl ikke noget problem. Kan det da ske at den ikke bliver oprettet? Og hvis ja, hvad skal jeg så gøre ved det? Prøve igen?
Hmm... Nu har du vel ikke gjort sådan noget i den her retning vel? (MEGET simplificeret)
RAM *pRam;
/* En hel masse kode her... Men intet der får pRam til at henvise til et validt objekt */
pRam->Afgiv();
De gange hvor jeg har set et stykke kode "gå ned med et brag" i første linje i en funktion (Hvis ikke din DEBUG_ON er defineret), har det været sådan noget i den retning. Altså koden prøver at kalde funktionen, i et objekt der ikke findes.
PS!!! Hvis IKKE det her er et projekt i forbindelse med et arbejde, skal du bare sige til så vil jeg da gerne hjælpe med at kigge lidt på det, hvis du kan emaile hele projektet. Arbejdsløs lige nu, så trænger til lidt beskæftigelsesterapi ;)... Poster kun min mail hvis du bruger en kompiler jeg har, og hvis du vil sende projektet.
erikjacobsen: Ja, selvfølgelig returnerer ceil et heltal, det er vel meningen med funktionen, men en double kan jo også indeholde et heltal. Sådan er ceil erklæret i math.h hos mig: double ceil (double);
mbulow: Nej, for søren. RAM eksisterer skam. Det er slet ikke det, som er problemet.
Tak for tilbudet. Det er i forbindelse med et min hovedopgave og ikke arbejde. Problemet er derimod kun at finde på XP/2000, så det gør ikke så meget at jeg ikke får det løst. (Selvom det selvfølgelig kunne tyde på at der er noget væsentligt galt med koden)
Hvis du har lyst til at lade mig kigge på det skal du være velkommen til at sende det til mig: mbulow@mail.tele.dk
Det KAN jo være jeg kan finde noget :) Og ikke for at gøre dig nervøs over noget, men det ville da være uheldigt hvis en censor lige prøver at køre programmet på en 2000/XP og det så går ned med et brag, pga. en lille bagatel :)
Eller censor opdager den programmeringsbøf, der sikkert ligger bag. Et eller andet sted.
Ja, en ceil giver et heltal, som jeg siger, men jeg fik vist ikke forklaret mig helt :) Den kan ikke give hverken en int eller long, da argumentet er en double, og dermed kan blive langt større end den største long. Dermed ville ceil kunne give en "fejl", som er svær at have med at gøre (ingen exceptions i C). En programmør, der ved det giver mening har så lov til at skrive
long x = (long)ceil(whatever)
og selv tage ansvaret.
PS: Lover I at fortælle os hvor fejlen egentlig er? Vi andre har jo bare gættet...
debug1305 wrote: >Jeg bruger ingen returkode/fejlmeddelelse da funktionen altid skal >lykkes. Og ingen exceptionhåndtering.
Fordi du allokerer memory dynamisk, vil der altid være en reel mulighed for, at funktionen IKKE lykkes (fordi der simpelthen ikke er nok memory). Du kan så selvfølgelig vælge at afslutte programmet med det samme med en exit(1)... Jeg vil gå ud fra, at en censor kigger på, om man husker at checke, at det, der returneres fra new, faktisk er en gyldig adresse.
Jeg er ret overbevist om at fejlen må skyldes at du kalder metoden for et objekt der ikke eksisterer eller måske ikke helt er af RAM klassen. Prøv lige at checke det først i afgiv metoden.
Prøv f.eks. noget i retning af følgende og se om fejlen flytter sig:
char *RAM::afgiv() { #ifdef DEBUG_ON printf("RAM::afgiv()\n"); #endif //beregn antal MB ram rundet op til nærmeste 4 MB double total = m.dwTotalPhys; total = ceil(total/(1048576*4))*4; #ifdef DEBUG_ON printf("Kalder new\n"); #endif char *ret = new char[64]; #ifdef DEBUG_ON printf("...done\n"); #endif ret[0] = 0; sprintf(ret,"hardware=[%d#%d#[[%d#'%.f MB']]]",kode,0,0,total); return ret; }
erikjacobsen>> Det giver jo slet ingen mening at prøve det når programmet afslutter inden array'et bliver oprettet.
Jeg har stadig ikke fundet ud af hvad problemet er, men jeg har skrevet funktionen om med inspiration fra soreno, så pointene går til ham, når han laver et svar til.
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.