[C] Tweedimensionale arrays

Pagina: 1
Acties:

  • Marc
  • Registratie: November 2001
  • Laatst online: 01-12-2021
ik zit met het volgende probleem:

ik wil een programma in C maken (onder linux) waarin de gebruiker een bericht kan intypen.
dit bericht zal later in het programma naar een server gestuurd worden.
hiervoor heb ik de volgende code geschreven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
...
int i, socket;
char body[500][500];
printf("please enter your message(end with a \".\"):\n\n");
for (i = 0; strncmp(body[i - 1], ".", 1) != 0; i++)
    fgets(body[i], 500, stdin);
printf("\nok, saved you message.\n\n");...
printf("sending message...\n");
for (i = 0; body[i] != NULL; i++)
    write(socket, body[i], strlen(body[i]));
printf("done!\n");
...

als ik het programma run:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
[sanchez@vncsmind coding]$ ./test
please enter your message(end with a \".\"):

blaat
blaater
blaatst
buh
.

ok, saved you message.
sending message...
Segmentation fault
[sanchez@vncsmind coding]$

hmm, hier gaat dus iets fout. als ik dit in mijn code verander:
code:
1
2
3
4
5
6
...
printf("sending message...\n");
for (i = 0; body[i] != NULL; i++) {
    write(socket, body[i], strlen(body[i]));
    printf("++ %d\n" i + 1);
printf("done!\n");...

krijg ik de volgende output:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[sanchez@vncsmind coding]$ ./test
...
ok, saved you message.
sending message...
++ 1
++ 2
++ 3
++ 4
++ 5
++ 6
...
++ 505
++ 506
++ 507
Segmentation fault
[sanchez@vncsmind coding]$

het lijkt er dus op dat hij bij
for (i = 0; body[i] != NULL; i++)
nooit bij een string komt die NULL is, heeft iemand misschien een idee wat ik kan doen?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Je initialiseert je body-array ook niet...

Verwijderd

Je neemt een array van chars, maar die hebben nog geen standaard waarde, in C is dit niet standaard NULL, kortom, je wil eerst je array vullen met 0-en, zodat je zeker weet dat als je er niets anders neerzet je in ieder geval een 0 tegenkomt.

Verder is het ook verstandig om (ook al zal het niet zo vaak voorkomen) toch te checken of je in de inlees loop niet over de 500 regels heengaat, want dan segfault het programma ook waarschijnlijk (momenteel kan dit dus).

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Op vrijdag 03 mei 2002 19:38 schreef Nem0 het volgende:
Je neemt een array van chars, maar die hebben nog geen standaard waarde, in C is dit niet standaard NULL, kortom, je wil eerst je array vullen met 0-en, zodat je zeker weet dat als je er niets anders neerzet je in ieder geval een 0 tegenkomt.
Tja, dan nog zal body[x] nooit NULL zijn. Je initialiseert een array van arrays, niet een array van pointers.

Ik vind dit sowieso een lelijke implementatie. Maak gewoon een queue met dynamisch gealloceerde pointers als elementwaarden. Dan hoef je geen beperkingen op de lengte of het aantal van de ingevoerde regels te stellen en tegelijkertijd niet overdreven veel geheugen te alloceren.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 03 mei 2002 19:41 schreef Soultaker het volgende:

[..]

Tja, dan nog zal body[x] nooit NULL zijn. Je initialiseert een array van arrays, niet een array van pointers.

Ik vind dit sowieso een lelijke implementatie. Maak gewoon een queue met dynamisch gealloceerde pointers als elementwaarden. Dan hoef je geen beperkingen op de lengte of het aantal van de ingevoerde regels te stellen en tegelijkertijd niet overdreven veel geheugen te alloceren.
achja unix en C++ schijnen niet samen te gaan >:) ;)

Verwijderd

Op vrijdag 03 mei 2002 20:20 schreef Orphix het volgende:

[..]

achja unix en C++ schijnen niet samen te gaan >:) ;)
onzin

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 06-09 22:39
Op vrijdag 03 mei 2002 19:41 schreef Soultaker het volgende:
Tja, dan nog zal body[x] nooit NULL zijn. Je initialiseert een array van arrays, niet een array van pointers.
memset?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Remenic
  • Registratie: Juni 2001
  • Laatst online: 09-08 20:06
Op vrijdag 03 mei 2002 20:20 schreef Orphix het volgende:

[..]

achja unix en C++ schijnen niet samen te gaan >:) ;)
|:( dit is C |:(

offtopic:
En onder UNIX is C++ prima, alleen als je GCC gebruikt laat de performance een beetje teveel wensen over, maar in ruil daarvoor krijg je wel een compiler die op heel veel platformen werkt, waardoor je dus niet voor elk platform (en compiler) aparte code hoeft te schrijven.

Maar goed, dat fabeltje heeft dus te maken met GCC, en bijvoorbeeld niet ICC (de Intel Compiler Collection), dus het is geen algemeen UNIX probleem.


edit:

hier stond onzin... :P

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

heej Orphix, toch wel grappig om te zien hoeveel mensen er knipoog-smile-blind zijn, wat jij? :+

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op zondag 05 mei 2002 00:52 schreef .oisyn het volgende:
heej Orphix, toch wel grappig om te zien hoeveel mensen er knipoog-smile-blind zijn, wat jij? :+
hehe, ja alsof ze zich aangevallen voelen :P

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op zaterdag 04 mei 2002 11:56 schreef farlane het volgende:
memset?
Of dit:
code:
1
char body[500][500] = {0};

Zou ook moeten werken :)

Professionele website nodig?


Verwijderd

Dat is de eerste keer dat ik deze constructie zie, verklaar je nader...

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op zondag 05 mei 2002 18:47 schreef Zagato het volgende:
Dat is de eerste keer dat ik deze constructie zie, verklaar je nader...
Met deze constructie (nitializer list) kan je een array tijdens het compileren al initialiseren. vb
code:
1
int array[3] = { 3, 5, 9 };

Maar voor de waardes die niet expliciet worden opgegeven wordt de waarde op 0 gesteld. (Dat is niet hetzelfde als geen initializer list gebruiken, omdat de waarden in de array dan undefined zijn!)
Het resultaat is dus een array van 500x500 met alles waardes op 0.

Het is in dit geval denk ik ook nog effectiever omdat de waardes niet at run-time nogmaals op 0 hoeft te worden gezet, maar dat het direct goed naar de stack kan worden gekopieerd.

  • iznogood
  • Registratie: September 2001
  • Niet online
for (i = 0; body[i] != ""; i++) ?

Just as Good


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op zondag 05 mei 2002 19:12 schreef iznogood het volgende:
for (i = 0; body[i] != ""; i++) ?
tja :{

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op zondag 05 mei 2002 19:12 schreef iznogood het volgende:
for (i = 0; body[i] != ""; i++) ?
ouch, dat doet pijn

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • windancer
  • Registratie: Maart 2000
  • Laatst online: 08-09 01:06
Wat je zelfs kunt doen is de variable filescope te geven. Alle variabelen die filescope hebben worden automatisch op nul geinitialiseerd.
Op zondag 05 mei 2002 19:08 schreef Orphix het volgende:

[..]

Met deze constructie (nitializer list) kan je een array tijdens het compileren al initialiseren. vb
code:
1
int array[3] = { 3, 5, 9 };

Maar voor de waardes die niet expliciet worden opgegeven wordt de waarde op 0 gesteld. (Dat is niet hetzelfde als geen initializer list gebruiken, omdat de waarden in de array dan undefined zijn!)
Het resultaat is dus een array van 500x500 met alles waardes op 0.

Het is in dit geval denk ik ook nog effectiever omdat de waardes niet at run-time nogmaals op 0 hoeft te worden gezet, maar dat het direct goed naar de stack kan worden gekopieerd.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op zondag 05 mei 2002 19:28 schreef windancer het volgende:
Wat je zelfs kunt doen is de variable filescope te geven. Alle variabelen die filescope hebben worden automatisch op nul geinitialiseerd.
ik vraag me af of dat standaard is... het kan natuurlijk net zo goed in de BSS section komen te staan (en dus niet worden geinitialiseerd)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • windancer
  • Registratie: Maart 2000
  • Laatst online: 08-09 01:06
Nope, K&R zeggen zelfs in hun bijbel dat het zo is.
Op zondag 05 mei 2002 19:33 schreef .oisyn het volgende:

[..]

ik vraag me af of dat standaard is... het kan natuurlijk net zo goed in de BSS section komen te staan (en dus niet worden geinitialiseert)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

ah ok :)

(het leest trouwens prettiger als je je reply onder de quote zet ipv erboven... (en het leest overigens nog prettiger als je gewoon helemaal niet quote als er geen andere posts tussen zitten ;))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Marc
  • Registratie: November 2001
  • Laatst online: 01-12-2021
iedereen bedankt voor zijn/haar hulp :)
ik heb het probleem op de volgende manier opgelost:
code:
1
2
3
4
5
printf("please enter your message(end with a \".\"):\n\n");
for (i = 0; (strncmp(body[i - 1], ".\n", 2) != 0) && (i < 500); i++)
    fgets(body[i], 500, stdin);

printf("\nok, saved you message.\n\n");...

hier zat dus ook nog een bug, als de gebruiker nu:
.hallo
zou invoeren, zou het programma meteen stoppen met inlezen, dit was niet bedoeling daar hij pas moest stoppen als de gebruiker alleen:
.
opgaf.
code:
1
2
3
for (i = 0; strncmp(body[i - 1], ".\n", 2) != 0; i++)
    write(sockfd, body[i], strlen(body[i]));
printf("done!\n\n");

vrij simpel, hij zoekt gewoon naar die ene . die de gebruiker heeft opgegeven bij het invoeren van de message.
als hij deze heeft gevonden, stopt hij.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op zondag 05 mei 2002 19:28 schreef windancer het volgende:
Wat je zelfs kunt doen is de variable filescope te geven. Alle variabelen die filescope hebben worden automatisch op nul geinitialiseerd.
Voor static geldt hetzelfde... Maar natuurlijk zijn globale of static variabelen in dit geval wel een uitnodiging voor multithreaded problemen, wat bij een chatserver allesbehalve een fictieve doelstelling is.

Professionele website nodig?

Pagina: 1