/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Om linkede lister
Fra : Morten


Dato : 27-12-01 00:01

Hej.
Jeg er netop nu igang med, at lære noget om linkede lister fran en bog
(Teach Yourself C in 21 days) og har i den forbindelse prøvet, at indtaste
nedenstående program, som demonstrere dette. Jeg anvender MS Visual C++ 6.0a
og mit OS er Windows 2000pro:
Filename: List15_12.c
/* Demonstrates the fundamentals of using */
/* a linked list. */

1: /* Demonstrates the fundamentals of using */
2: /* a linked list. */
3:
4: #include <stdlib.h>
5: #include <stdio.h>
6: #include <string.h>
7:
8: /* The list data structure. */
9: struct data {
10: char name[20];
11: struct data *next;
12: };
13:
14: /* Define typedefs for the structure */
15: /* and a pointer to it. */
16: typedef struct data PERSON;
17: typedef PERSON *LINK;
18:
19: main()
20: {
21: /* Head, new, and current element pointers. */
22: LINK head = NULL;
23: LINK new = NULL;
24: LINK current = NULL;
25:
26: /* Add the first list element. We do not */
27: /* assume the list is empty, although in */
28: /* this demo program it always will be. */
29:
30: new = (LINK)malloc(sizeof(PERSON));
31: new->next = head;
32: head = new;
33: strcpy(new->name, "Abigail");
34:
35: /* Add an element to the end of the list. */
36: /* We assume the list contains at least one element. */
37:
38: current = head;
39: while (current->next != NULL)
40: {
41: current = current->next;
42: }
43:
44: new = (LINK)malloc(sizeof(PERSON));
45: current->next = new;
46: new->next = NULL;
47: strcpy(new->name, "Catherine");
48:
49: /* Add a new element at the second position in the list. */
50: new = (LINK)malloc(sizeof(PERSON));
51: new->next = head->next;
52: head->next = new;
53: strcpy(new->name, "Beatrice");
54:
55: /* Print all data items in order. */
56: current = head;
57: while (current != NULL)
58: {
59: printf("\n%s", current->name);
60: current = current->next;
61: }
62:
63: printf("\n");
64: return(0);
65: }
Ovenstående kan sagtens både compiles og linkes til en *.exe fil, men hvis
jeg derefter vil udfører programmet kommer operativsystemet med følgende
programfejl:
"Instruktionen ved "0x0030103a" refererede hukommelse ved "0x00000014".
Hukommelsen kunne ikke "written"."
Hvis jeg derefter vælger, at udfører en fejlfinding med MSVC's debug
funktion før jeg følgende meddelse:
"Unhandled exception in List15_12.exe: 0xC0000005: Access Violation."

Efter at have debugget prorgammet i MSVC er jeg kommet frem til, at
undtagelsen genereres ved linje 45 ( current->next = new; ).
Er programmet skrevet forkert(hvilket jeg ikke mener), mangler jeg en
service pack til min Visual C++, eller hvad kan årsagen ellers være.

Venlig hilsen: Morten



 
 
Ulrik Magnusson (27-12-2001)
Kommentar
Fra : Ulrik Magnusson


Dato : 27-12-01 01:45



Morten wrote:

> Hej.
> Jeg er netop nu igang med, at lære noget om linkede lister fran en bog
> (Teach Yourself C in 21 days) og har i den forbindelse prøvet, at indtaste
> nedenstående program, som demonstrere dette. Jeg anvender MS Visual C++ 6.0a
> og mit OS er Windows 2000pro:
> Filename: List15_12.c

[SNIP]

> Efter at have debugget prorgammet i MSVC er jeg kommet frem til, at
> undtagelsen genereres ved linje 45 ( current->next = new; ).
> Er programmet skrevet forkert(hvilket jeg ikke mener), mangler jeg en
> service pack til min Visual C++, eller hvad kan årsagen ellers være.

Prøv at skifte "new" ud med "newLink" eller lignende - "new" er et
nøgleord i C++, og jeg forstår ikke helt at compileren har accepteret din
kode. Da "new" forsvandt, fungerede det fint (VC++ 6.0 på Windows 98),
og programmet skriver følgende ud:

Abigail
Beatrice
Catherine

Ulrik Magnusson

PS: Undgå venligst linienumre i kildekoden næste gang - de er lidt
træls at fjerne - ellers indsæt dem med /**/ omkring, så det er lige til
at copy/paste og compilere.


Ulrik Magnusson (27-12-2001)
Kommentar
Fra : Ulrik Magnusson


Dato : 27-12-01 02:01



Ulrik Magnusson wrote:

> Morten wrote:
>
> > Hej.
> > Jeg er netop nu igang med, at lære noget om linkede lister fran en bog
> > (Teach Yourself C in 21 days) og har i den forbindelse prøvet, at indtaste
> > nedenstående program, som demonstrere dette. Jeg anvender MS Visual C++ 6.0a
> > og mit OS er Windows 2000pro:
> > Filename: List15_12.c

og C er ikke det samme som C++ - i C er "new" ikke nøgleord og du var
sikkert bedre tjent med en ren C compiler, for at undgå den slags forvirring.
Tag evt. et kig på www.delorie.com - gcc.exe er C-compileren og
gpp.exe C++-compileren.

Ulrik Magnusson


Bertel Lund Hansen (27-12-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 27-12-01 08:41

Ulrik Magnusson skrev:

>og C er ikke det samme som C++ - i C er "new" ikke nøgleord og du var
>sikkert bedre tjent med en ren C compiler

Måske, men det kan da godt være en fordel at man vænner sig til
ikke at bruge andre sprogs kodeord som variable, især da C++'s i
C.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Igor V. Rafienko (27-12-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 27-12-01 09:17

[ Bertel Lund Hansen ]

[ snip ]

> Måske, men det kan da godt være en fordel at man vænner sig til ikke
> at bruge andre sprogs kodeord som variable, især da C++'s i C.


.... fordi at? 'catch', 'explicit', 'typename' og 'friend' er da
fullgode variabelnavn. For å ikke nevne at lambda, raise osv. burde
kunne brukes i C uten betenkninger.





ivr
--
Haskell to the people!

Morten (27-12-2001)
Kommentar
Fra : Morten


Dato : 27-12-01 15:26


"Ulrik Magnusson" <ulrikm@yahoo.com> skrev i en meddelelse
news:3C2A6EF3.4D847B1A@yahoo.com...
>
>
> Morten wrote:
>...
> > Efter at have debugget prorgammet i MSVC er jeg kommet frem til, at
> > undtagelsen genereres ved linje 45 ( current->next = new; ).
> > Er programmet skrevet forkert(hvilket jeg ikke mener), mangler jeg en
> > service pack til min Visual C++, eller hvad kan årsagen ellers være.
>
> Prøv at skifte "new" ud med "newLink" eller lignende - "new" er et
> nøgleord i C++, og jeg forstår ikke helt at compileren har accepteret din
> kode. Da "new" forsvandt, fungerede det fint (VC++ 6.0 på Windows 98),
> og programmet skriver følgende ud:
>
> Abigail
> Beatrice
> Catherine
>
> Ulrik Magnusson
>
Jeg har prøvet, at ændre "new" variablen til "newLink" og dette gjorde ingen
forskel. Jeg vil gerne understrege, at jeg bruger Windows 2000pro og netop
dette operativsystem, som jo bygger på NT, er meget mere sriks når det
drejer sig om direkte hukommelses tilgang; modsat f.eks. Windows 9x. Det er
altså ikke en fejl i kildekoden, der foresager fejlen, men derimod
operativsystemet som griber ind og stopper programmet. Muligvis er det linje
45 ( current->next = new; ), der forsager fejlen. Det er i hvert fald der
debuggeren/systemet stopper programmet og viser meddelsen:
"Unhandled exception in List15_12.exe: 0xC0000005: Access Violation.".
Men det virker tilsyneladende under windows98, hvorfor så ikke under Windows
2000pro?

P.S. Tak for påmindelsen med de der linje numre.
Mvh: Morten



J Skantse (28-12-2001)
Kommentar
Fra : J Skantse


Dato : 28-12-01 13:38


"Morten" <mozart@mobilixnet.dk> wrote in message
news:%cGW7.120$aU6.345793666@news.orangenet.dk...
> [snip]
> Jeg har prøvet, at ændre "new" variablen til "newLink" og dette gjorde
ingen
> forskel.
>[snip]
>. Muligvis er det linje
> 45 ( current->next = new; ), der forsager fejlen.

Kører fint her under win 2000.

Har du skiftet new ud med newLink alle steder i koden (altså også i linie
45.. ??




mvh/Jørgen



Morten (28-12-2001)
Kommentar
Fra : Morten


Dato : 28-12-01 15:41

"Morten"
>> [snip]
> >Jeg har prøvet, at ændre "new" variablen til "newLink" og dette gjorde
ingen
> >forskel.
>>[snip]
>>Muligvis er det linje
>> 45 ( current->next = new; ), der forsager fejlen.

>Kører fint her under win 2000.
>
>Har du skiftet new ud med newLink alle steder i koden (altså også i linie
>45.. ??

Ja, jeg HAR skiftet alle forekomster af "new" ud med "newLink".
Præcis hvilken version af Visual C++ har du? Jeg har VC++ 6.0 uden nogen
service parks. Kan det måske være det der er galt?

Mvh.: Morten




Mogens Hansen (28-12-2001)
Kommentar
Fra : Mogens Hansen


Dato : 28-12-01 16:38

Hej Morten,

"Morten" <mozart@mobilixnet.dk> wrote

> "Unhandled exception in List15_12.exe: 0xC0000005: Access Violation.".
> Men det virker tilsyneladende under windows98, hvorfor så ikke under
Windows
> 2000pro?
>

Der er ikke særligt meget galt med den kode du postede oprindeligt:

Du bør teste på om "malloc" faktisk er i stand til at allokere noget
hukommelse (test på om malloc returnerer NULL).
Hvis den kan det, er der så vidt jeg kan se ikke noget i den kode du postede
i det oprindelige indlæg, som bør give en "Access Violation" fejl, når det
oversættes som et C program. Det burde gælde både under Windows 9x og
Windows NT/2000/XP (og stort set alle andre operativ-systemer for den sags
skyld).

"main" bør returnere int, så linien
main()
bør ændres til
int main(void)

Den hukommelse som er allokeret med "malloc" frigives med "free". Nogle vil
være uenige med mig på det punkt, men det er et skråplan ikke at rydde op
efter sig (sagde mor).

Hvis du fortsat har problemer, når du tester på at "malloc" returnerer noget
hukommelse (og det vil undre mig, hvis den ikke gør), så ville jeg undersøge
om du bruger run-time library i et DLL og om det er samme version der er
installeret på din Windows 98 og din Windows 2000.
Jeg vil desuden klart anbefale at linke run-time library statisk i dit
program.

Jeg syntes på visse punkter at koden kunne være tydeligere - men det er en
anden sag.
Jeg foretrækker en struktur, hvor hukommelsen allokeres, hukommelsen
initialiseres og hukommelsen bruges i nævnte rækkefølge:

/* Demonstrates the fundamentals of using */
/* a linked list. */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* The list data structure. */
typedef struct data
{
char name[20];
struct data *next;
} PERSON;

int main(void)
{
/* Head, new, and current element pointers. */
PERSON* head = NULL;
PERSON* new = NULL;
PERSON* current = NULL;

/* Add the first list element. We do not */
/* assume the list is empty, although in */
/* this demo program it always will be. */

new = malloc(sizeof(PERSON));
if(!new) {
return EXIT_FAILURE;
}
strcpy(new->name, "Abigail");
new->next = NULL;

head = new;

/* Add an element to the end of the list. */
/* We assume the list contains at least one element. */

new = malloc(sizeof(PERSON));
if(!new) {
current = head;
while(current) {
new = current;
current = current->next;
free(new);
}
return EXIT_FAILURE;
}
strcpy(new->name, "Catherine");
new->next = NULL;

current = head;
while (current->next != NULL)
{
current = current->next;
}
current->next = new;

/* Add a new element at the second position in the list. */
new = malloc(sizeof(PERSON));
if(!new) {
current = head;
while(current) {
new = current;
current = current->next;
free(new);
}
return EXIT_FAILURE;
}
strcpy(new->name, "Beatrice");
new->next = NULL;

while (current->next != NULL)
{
current = current->next;
}
current->next = new;

/* Print all data items in order. */
current = head;
while (current != NULL)
{
printf("\n%s", current->name);
current = current->next;
}

printf("\n");
current = head;
while(current) {
new = current;
current = current->next;
free(new);
}
return 0;
}


Der er åbenlyst plads til forbedring, ved at lave nogle funktioner der
udfører de enkelte trin:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* The list data structure. */
typedef struct data
{
char name[20];
struct data *next;
} PERSON;

PERSON* append_new_person(PERSON** first_person, const char* name)
{
PERSON* new_person = malloc(sizeof(PERSON));
if(!new_person) {
return NULL;
}

// initialize memory
new_person->next = NULL;
strcpy(new_person->name, name);

// append to linked list
while(*first_person) {
first_person = &(*first_person)->next;
}
*first_person = new_person;

return new_person;
}

void free_person_list(PERSON* first_person)
{
PERSON* to_free;
while(first_person) {
to_free = first_person;
first_person = first_person->next;
free(to_free);
}
}

int main(void)
{
/* Head, new, and current element pointers. */
PERSON* head = NULL;
PERSON* current = NULL;

if(!append_new_person(&head, "Abigail")) {
// no need to free at this point
return EXIT_FAILURE;
}

if(!append_new_person(&head, "Catherine")) {
free_person_list(head);
return EXIT_FAILURE;
}

if(!append_new_person(&head, "Beatrice")) {
free_person_list(head);
return EXIT_FAILURE;
}

/* Print all data items in order. */
current = head;
while (current != NULL)
{
printf("%s\n", current->name);
current = current->next;
}

free_person_list(head);
return EXIT_SUCCESS ;
}

Hvad syntes du ?

Venlig hilsen

Mogens Hansen



Morten (29-12-2001)
Kommentar
Fra : Morten


Dato : 29-12-01 01:16


"Mogens Hansen" <mogens_h@dk-online.dk> skrev i en meddelelse
news:a0i3h6$o6d$1@news.cybercity.dk...
> Hej Morten,
>
> "Morten" <mozart@mobilixnet.dk> wrote
>
> > "Unhandled exception in List15_12.exe: 0xC0000005: Access Violation.".
> > Men det virker tilsyneladende under windows98, hvorfor så ikke under
> Windows
> > 2000pro?
> >
>
> Der er ikke særligt meget galt med den kode du postede oprindeligt:
> Mogens Hansen
Hihi.
Nej, det var der ikke, men det var der med den kode jeg faktisk brugte i
compileren.
I linje 39 stod der:
39: while (current->next != NULL)
men i virkeligheden havde jeg skrevet:
while (current->name != NULL)
En simpel fejl og dog nok til, at operativsystemet greb ind. Jeg vil også
lige nævne at jeg bl.a. prøvede at compile programmet med DJGPP, hvilket
ikke resulterede i en Access Violation. Den enste fejl var dog, at
"Catherine" ikke bliv udskrevet.
Men tak alligevel for alle de gode foreslag, men næste gang jeg står med et
program vil jeg nok lige tælle til ti, og lige kigge kildekoden efter i
sømmene, inden jeg farer i blækhuset.
Mvh.: Morten



Mogens Hansen (29-12-2001)
Kommentar
Fra : Mogens Hansen


Dato : 29-12-01 10:16

"Morten" <mozart@mobilixnet.dk> wrote
>
> "Mogens Hansen" <mogens_h@dk-online.dk> skrev i en meddelelse

> >
> > Der er ikke særligt meget galt med den kode du postede oprindeligt:

> Nej, det var der ikke, men det var der med den kode jeg faktisk brugte i
> compileren.

Det gør det jo unægteligt noget sværere at få fornuftig hjælp.

> I linje 39 stod der:
> 39: while (current->next != NULL)
> men i virkeligheden havde jeg skrevet:
> while (current->name != NULL)
> En simpel fejl og dog nok til, at operativsystemet greb ind.

Heldigvis!
Generelt vil jeg anbefale at man bruger værktøjer som f.eks. Borland
CodeGuard (som jeg foretrækker), Rational Purify eller NuMega BoundsChecker
når man udvikler programmer. De er (naturligvis) bedre til at finde fejl i
programmerne end operativsystemerne og bedre end man selv er. Mange software
fejl ville være undgået hvis de blev brugt generelt.

> Jeg vil også
> lige nævne at jeg bl.a. prøvede at compile programmet med DJGPP, hvilket
> ikke resulterede i en Access Violation.

Og hvad kan man så lære af det ?
At det der formelt hedder "undefined behavior" (§3.18 i C Standarden, og
§1.3.12 i C++ Standarden) giver uforudsigelig opførsel - men det er ikke
overraskende.
Man kan intet konkludere om kvaliteten af det ene operativ system i forhold
til det andet, eller den ene compiler i forhold til den anden.

> Den enste fejl var dog, at
> "Catherine" ikke bliv udskrevet.

Det er den eneste fejl, som du umiddelbart kunne konstatere, hvilket ikke
nødvendigvis er det samme som at det er den eneste fejl i programmet.


Venlig hilsen

Mogens Hansen



Jesper Gødvad (28-12-2001)
Kommentar
Fra : Jesper Gødvad


Dato : 28-12-01 14:34



> Ovenstående kan sagtens både compiles og linkes til en *.exe fil, men hvis
> jeg derefter vil udfører programmet kommer operativsystemet med følgende
> programfejl:
> "Instruktionen ved "0x0030103a" refererede hukommelse ved "0x00000014".
> Hukommelsen kunne ikke "written"."

Lav en ny swap/page fil og forsøg igen.

mvh. jesper



Mogens Hansen (28-12-2001)
Kommentar
Fra : Mogens Hansen


Dato : 28-12-01 16:53


"Morten" <mozart@mobilixnet.dk> wrote

> "Instruktionen ved "0x0030103a" refererede hukommelse ved "0x00000014".
> Hukommelsen kunne ikke "written"."
> Hvis jeg derefter vælger, at udfører en fejlfinding med MSVC's debug
> funktion før jeg følgende meddelse:
> "Unhandled exception in List15_12.exe: 0xC0000005: Access Violation."
>
> Efter at have debugget prorgammet i MSVC er jeg kommet frem til, at
> undtagelsen genereres ved linje 45 ( current->next = new; ).

Hvilken værdi har "current" på det sted ?
Kig med debuggeren.
Jeg gætter på at den er NULL.
0x14 passer netop med adressen på hvor "current->next" ligger når "current"
er NULL.
Du har ikke testet på om malloc var i stand til at allokere hukommelse.

Venlig hilsen

Mogens Hansen



Søg
Reklame
Statistik
Spørgsmål : 177552
Tips : 31968
Nyheder : 719565
Indlæg : 6408847
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste