[C] Hele korte vraag over char pointers

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 08-10 00:28
Voor een schoolopdracht moet ik een char pointer array vullen met woorden uit een .txt bestand. Dit lukt gedeeltelijk maar als ik de code run zijn alle posities in de array gevuld met het laatst ingelezen woord.

Ik heb vanalles geprobeerd en vermoed zelf dat ik iets fout doe met het gebruik van de pointer. Ik heb alle relavente code samengevat in een heel klein programmaatje. Hopelijk ziet iemand in één oogopslag wat ik fout doe?

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdlib.h>

char *word[100];
char tempWord[100];
int wordCount = 0;
FILE *fp;

main()
{
   //Probeer het bestand te openen
   if((fp = fopen("words.txt", "r")) == NULL) {
      printf("Fout bij het openen van words.txt \n");
      exit(1);
   }
  
   //Loop door het bestand tot er geen nieuwe woorden meer gevonden worden
   while (fgets(tempWord, 100, fp) != NULL) {
      word[wordCount] = tempWord;
      printf("Current woordCount: %d\n", wordCount);
      printf("Current woord: %s", tempWord);
      printf("Eerste woord in bestand: %s", word[0]);
      printf("Laatste woord in bestand: %s\n", word[wordCount]);
      wordCount++;
   }
   fclose(fp);
}

Alle reacties


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Je mist malloc() en strcpy(), nu wordt steeds de zelfde tempWord pointer gebruikt.
Na het gebruik moet je wel voor elke free() aanroepen.

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Je laat elke pointer in je array 'word' verwijzen naar hetzelfde adres: 'tempWord'. Daar staat op het eind van je algoritme het laatste woord in.

spoiler:
Je moet het woord dat je ingelezen hebt, op de heap opslaan (calloc of malloc al gehad?)

Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 08-10 00:28
Bedankt voor de antwoorden

Ik heb

word[wordCount] = tempWord;

vervangen door;

strcpy(word[wordCount], tempWord);

Nu geeft het programma een segmentation fout, waarschijnlijk omdat het een stukje geheugen probeerd te benaderen waar het niet bij mag? Moet ik dit oplossen met malloc()? Ik vind het dynamisch beheren van geheugen nog vrij lastig, iemand die mij op weg kan helpen met de juiste syntax?

Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
Je 'word' array kan je niet vullen met tekst. Het is een array van pointers, en die moeten pointen naar waar de data staat. Jij kopieert nu de tekst naar de pointer array, maar die moeten dus alleen pointer naar de woorden. En dus moet je iets hebben waar je wel de woorden kan opslaan, zoals met malloc.

Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Sissors schreef op dinsdag 16 februari 2016 @ 21:51:
Je 'word' array kan je niet vullen met tekst.
Dat doet hij ook niet. Hij kopieert nu de string uit tempWord naar het adres in 'word[wordCount]'. Dat is opzich goed.

Het probleem is nu dat 'word[wordCount]' nog niet verwijst naar een stukje geheugen dat je mag beschrijven. Zo'n stukje geheugen kan je krijgen door malloc aan te roepen.

Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
Whoops my bad, even blond momentje. Maar nog steeds inderdaad, hij moet geheugen reserveren met malloc.

Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 08-10 00:28
Het is gelukt door:

word[wordCount] = malloc(sizeof(tempWord));

In de loop te plaatsen, is dit de juiste manier? Moet ik het gereserveerde geheugen weer vrij maken of gebeurd dat vanzelf? Hartelijk bedankt voor alle hulp tot nu toe.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-10 14:49
Dat gebeurt automatisch aan het einde van je programma. Maar in het algemeen wil je het, nadat je er mee hebt gedaan wat je wilt, weer vrijgeven met free(...).

Overigens heb je hier malloc niet nodig aangezien je toch maximaal 100 characters inleest met fgets, dus je kunt het array van strings ook statisch reserveren.

Daarbij moet gezegd worden dat je:
- Niet controleert of je meer dan 100 allocaties doet, dus potentieel buiten je pointer array aan het pielen gaat
- Maximaal 100 characters inleest met fgets, maar ook 100 characters malloc'ed waardoor je potentieel een string krijgt die niet terminated is met '\0' wat ook kan leiden naar de dark side of the force.

Anyways, happy coding. C FTW!

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.


Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Dat wordt een fijne buffer overflow :)

i3 + moederbord + geheugen kopen?


Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
farlane schreef op dinsdag 16 februari 2016 @ 23:10:
- Niet controleert of je meer dan 100 allocaties doet, dus potentieel buiten je pointer array aan het pielen gaat
Eens. Als wordCount 100 of meer is, gaat word[wordCount] fout. Zoals gezegd noemt men dit een "buffer overflow". Topic-starter moet dus iets schrijven om dit te voorkomen.
- Maximaal 100 characters inleest met fgets, maar ook 100 characters malloc'ed waardoor je potentieel een string krijgt die niet terminated is met '\0' wat ook kan leiden naar de dark side of the force.
Oneens. Het aantal dat je meegeeft aan fgets is inclusief de '\0'. Dat gaat dus goed.


Over strings in C
Een string is een rijtje karakters. Op een of andere manier moet je aangeven hoeveel het er zijn. Sommige talen slaan eerst het aantal op, maar C doet dit niet. C markeert het einde met een speciaal karakter: '\0'.

Het gevolg hiervan is, is dat als je een string van bv 8 karakters op wilt slaan, je 9 plekken nodig hebt.

Je kan dus ook dit doen (+ 1 is dus voor die extra '\0'):
word[wordCount] = malloc(strlen(tempWord) + 1);

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-10 14:49
Daos schreef op woensdag 17 februari 2016 @ 11:46:
[...]

Oneens. Het aantal dat je meegeeft aan fgets is inclusief de '\0'. Dat gaat dus goed.
Je hebt helemaal gelijk.

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.


Acties:
  • +1 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Overigens is strdup wel zo makkelijk hier. Dat combineert de strlen, malloc en strcpy.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1