Avatar billede debug1305 Nybegynder
16. oktober 2002 - 20:00 Der 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).
Avatar billede soreno Praktikant
16. oktober 2002 - 20:03 #1
koden ser da ganske fin ud - hvordan har du sporet dig ind på netop den linie ?
Avatar billede debug1305 Nybegynder
16. oktober 2002 - 20:09 #2
jeg har indsat nogle linier med printf("x") og fundet ud af at det er denne linie.
Avatar billede soreno Praktikant
16. oktober 2002 - 20:12 #3
prøv at poste koden lige omkring den linie du allerede har postet
Avatar billede debug1305 Nybegynder
16. oktober 2002 - 20:22 #4
char *RAM::afgiv() {
#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;
}
Avatar billede soreno Praktikant
16. oktober 2002 - 20:28 #5
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;
}
Avatar billede dittmer Nybegynder
16. oktober 2002 - 20:31 #6
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?

Mvh
Søren
Avatar billede erikjacobsen Ekspert
16. oktober 2002 - 20:33 #7
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"); }
Avatar billede erikjacobsen Ekspert
16. oktober 2002 - 20:35 #8
PS: hvor kommer variablen "kode" fra
Avatar billede soreno Praktikant
16. oktober 2002 - 20:37 #9
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 :-)
Avatar billede erikjacobsen Ekspert
16. oktober 2002 - 20:39 #10
Det er nu ellers måden at gøre det på, Søren :)
Avatar billede soreno Praktikant
16. oktober 2002 - 20:42 #11
så kan jeg da godt se hvorfor mange har svært ved at finde memoryleaks.. :-)
Avatar billede erikjacobsen Ekspert
16. oktober 2002 - 20:49 #12
"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 .. :)
Avatar billede debug1305 Nybegynder
16. oktober 2002 - 21:20 #13
til Søren:
Jeg mener bestemt at ceil returnerer en double, men det er heller ikke det, som er problemet.

Nej, det er ikke den samme linie, men jeg har haft samme problemer flere steder.

Jeg bruger ingen returkode/fejlmeddelelse da funktionen altid skal lykkes. Og ingen exceptionhåndtering.
Avatar billede debug1305 Nybegynder
16. oktober 2002 - 21:25 #14
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?
Avatar billede erikjacobsen Ekspert
16. oktober 2002 - 21:36 #15
Har du prøvet hvad jeg foreslår?  ceil giver pr definition en heltalsværdi
Avatar billede mbulow Nybegynder
16. oktober 2002 - 22:56 #16
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.
Avatar billede debug1305 Nybegynder
16. oktober 2002 - 23:20 #17
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);
Avatar billede debug1305 Nybegynder
16. oktober 2002 - 23:25 #18
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)
Avatar billede dittmer Nybegynder
16. oktober 2002 - 23:30 #19
Mea culpa. ceil returnerer en double, men jeg synes stadig det er noget konceptuelt rod.
Avatar billede mbulow Nybegynder
16. oktober 2002 - 23:34 #20
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 :)
Avatar billede erikjacobsen Ekspert
16. oktober 2002 - 23:42 #21
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...
Avatar billede jpk Nybegynder
17. oktober 2002 - 09:01 #22
Må man spørge hvorfor I ikke anvender en string i stedet for alt det bøvl med at oprette et char array?
Avatar billede jpk Nybegynder
17. oktober 2002 - 09:06 #23
Og hvorfor:
ret[0] = 0;
Det logiske ville da være:
ret[63] = 0; // Nulterminering af "strengen"
Avatar billede arne_v Ekspert
17. oktober 2002 - 10:16 #24
ceil returner en type double, men vil altid indeholde
et helt tal.

Hverken ret[0] = 0; eller ret[63] = 0; er nødvendige
da sprintf altid vil terminere.
Avatar billede ricelius Nybegynder
18. oktober 2002 - 00:22 #25
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.

char *ret = new char[64];
if(!ret)
{
    _tprintf(_T("Not enough memory available\n"));
    exit(1);
}
ret[0] = 0;
...

Dette er også UNICODE-kompatibelt, hvilket sikkert vil give bonuspoints... ;) Men det vil nok kun virke i VC++

-Ricelius
Avatar billede pchris Nybegynder
18. oktober 2002 - 13:44 #26
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;
}
Avatar billede debug1305 Nybegynder
18. oktober 2002 - 15:05 #27
Det har jeg checket. Programmet stopper efter printf("Kalder new\n"); eller før printf("...done\n");

Objektet findes og er af klassen RAM.
Avatar billede pchris Nybegynder
18. oktober 2002 - 15:15 #28
Så er jeg bange for at du er løbet tør for heap-plads.
Avatar billede debug1305 Nybegynder
18. oktober 2002 - 15:22 #29
Det er heller ikke tilfældet.
Avatar billede erikjacobsen Ekspert
18. oktober 2002 - 21:20 #30
Må vi lige få afklaret om du rent faktisk har testet:
  if(!ret)
og har prøvet at afsætte mere plads end de 64?
Avatar billede debug1305 Nybegynder
24. oktober 2002 - 11:22 #31
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.
Avatar billede soreno Praktikant
24. oktober 2002 - 12:02 #32
jamen, så gør jeg lige det
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester