[C++] cin doet gek

Pagina: 1
Acties:
  • 136 views sinds 30-01-2008
  • Reageer

  • defusion
  • Registratie: Juli 2003
  • Niet online
Ik heb de volgende code
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <string>
#include <iostream>

int main(int argc, char *argv[])
{
  char *name;

  cout << "Wat is je naam? ";
  cin >> name;
  //cout << "hoi " << name << endl;
  cout << "Je naam werd opgeslagen op de locatie " << &name << endl;

  //0x241ff5c
  int *memloc;
  char *name2;
  memloc = (int *) 0x241ff5c;
  name2 = (char *) *memloc;

  cout << name2 << endl;
  system("pause");
  return 0;
}


Nou werkt deze code perfect op mijn windows XP bak, maar op windows 2003, en op freebsd compileert hij wel, maar crasht ie.
Windows 2003 klaagt dat ie een geheugenlocatie niet kan lezen (niet 0x241ff5c, het gebeurt echt bij de cin, want als ik de rest uit comment werkt het ook niet)
en freebsd kan ik gewoon naam invoeren, en als ik op enter druk krijg ik een Segmentation fault (core dumped) te zien.

Wat kan hiervoor de reden zijn?
verder ligt het niet aan de compiler, want als ik van de windows xp bak de .exe gewoon kopieer heb ik hetzelfde probleem.

  • bimm
  • Registratie: November 2005
  • Laatst online: 08-03 22:16
Tenzij ik een banaan ben (en dat kan best, ben niet zo goed in c++) moet je eerst geheugen alloceren voor *name. Tenzij cin dat voor jou doet, maar dat denk ik van niet.

Ik ook, jij niet?


  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 23-04 21:46

LauPro

Prof Mierenneuke®

Heeft het niet te maken met die referentie? Een pointer is al een 'referentie' naar de geheugenlocatie op zichzelf, dus in dit geval kan je het ampesantteken gewoon weglaten lijkt me.

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 01:25

GrimaceODespair

eens een tettenman, altijd ...

met bimm, maar ook nog: waarom assign je "hard" een waarde aan een int pointer?

char* alloceert overigens alleen de plek om die pointer op te slaan, niet die pointer zelf.

[ Voor 42% gewijzigd door GrimaceODespair op 17-11-2005 16:53 ]

Wij onderbreken deze thread voor reclame:
http://kalders.be


  • defusion
  • Registratie: Juli 2003
  • Niet online
code:
1
2
3
char *onzin;
onzin = "mijn naam";
cout << onzin;

dat werkt toch ook gewoon? hoe bedoel je geheugen alloceren, doe ik dat met de char *variabele; niet?

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 01:25

GrimaceODespair

eens een tettenman, altijd ...

Daar is je (locale!) allocatie.

Wij onderbreken deze thread voor reclame:
http://kalders.be


  • bimm
  • Registratie: November 2005
  • Laatst online: 08-03 22:16
Nee, zoals Grimace zegt, dat alloc'ed alleen de ruimte voor de verwijzing naar een plaats in het geheugen. Niet een gereserveerde ruimte voor tekst. Je kunt het zien als een wegwijzer, die *name. Alleen,...de bestemming bestaat nog niet. En daar probeer je iets in te stoppen.

Ik ook, jij niet?


  • defusion
  • Registratie: Juli 2003
  • Niet online
Even voor de duidelijkheid, het gaat om cin, niet de rest, dus
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string>
#include <iostream>

int main(int argc, char *argv[])
{
  char *name;

  cout << "Wat is je naam? ";
  cin >> name;
  system("pause");
  return 0;
}

werkt ook niet

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 01:25

GrimaceODespair

eens een tettenman, altijd ...

defusion schreef op donderdag 17 november 2005 @ 16:56:
Even voor de duidelijkheid, het gaat om cin, niet de rest, dus
code:
1
2
  char *name;
  cin >> name;
name wijst nu naar ergens een locatie, maar die locatie ligt nog niet vast (en is nog niet gealloceerd)

Wij onderbreken deze thread voor reclame:
http://kalders.be


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Bovendien output je ook het adres van een pointer, niet de locatie waar je data staat, maar de locatie waar die pointer staat (op de stack)

  • defusion
  • Registratie: Juli 2003
  • Niet online
Dus is dit een windows probleem?
want windows xp begrijpt het wel 8)7

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

defusion schreef op donderdag 17 november 2005 @ 16:58:
Dus is dit een windows probleem?
want windows xp begrijpt het wel 8)7
nee het is brakke code ;)

  • Obliterator
  • Registratie: November 2000
  • Laatst online: 30-03 13:50
Dat het goed gaat is puur toeval.

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 01:25

GrimaceODespair

eens een tettenman, altijd ...

defusion schreef op donderdag 17 november 2005 @ 16:58:
Dus is dit een windows probleem?
want windows xp begrijpt het wel 8)7
Nee, het gaat, *afkloppen*, niet mis in XP...

edit: spuit 22 ...

[ Voor 5% gewijzigd door GrimaceODespair op 17-11-2005 16:59 ]

Wij onderbreken deze thread voor reclame:
http://kalders.be


  • devvy
  • Registratie: Augustus 2003
  • Laatst online: 16-02 18:56
Het is precies zoals eerder ook al is gezegd:
Wanneer je dit doet:
code:
1
char *name;


Dan is er geen geheugen gealloceerd voor name. Cin zal ook geen geheugen voor jou gaan alloceren! Dat betekent dat het gedrag ongedefinieerd is, en dat blijkt ook wel. Sommige systemen vinden het (helaas) goed dat je op een stuk ongealloceerd memory zit te schrijven, anderen nemen het wat serieuzer. Dus:

code:
1
2
char *name = new char[256];
cin >> name;

werkt een stuk beter.

https://photune.blogspot.com/


  • devvy
  • Registratie: Augustus 2003
  • Laatst online: 16-02 18:56
Nog een kleine toevoeging: Deze manier (ook degene die ik voorstel) is eigenlijk niet safe, omdat je van te voren niet kan garanderen hoeveel cin zal proberen te stoppen in jouw char array. Je kunt dit beter oplossen door een string class te gebruiken die ervoor zorgt dat er precies zoveel geheugen wordt gealloceerd als cin probeert te 'voeren'. Exacte voorbeelden heb ik niet bij de hand want ik gebruik cin nooit. Cin is echter van het type 'istream' voor zover ik weet, en dat betekent dat het een zogeheten 'stream' is - lees daar eens iets over, het is vast mogelijk om dit netjes op te lossen.

[ Voor 15% gewijzigd door devvy op 17-11-2005 17:04 . Reden: toevoeging! ]

https://photune.blogspot.com/


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-04 02:19
Het is C++. Gebruik in godsnaam gewoon een std::string:
C++:
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main()
{
    std::string naam;
    std::cin >> naam;
    std::cout << "Hoi, " << naam << std::endl;
}

  • defusion
  • Registratie: Juli 2003
  • Niet online
Ok, bedankt :)
new char werkt perfect. Ik was zelf al gaan spelen met het object string, maar dat werkt toch iets minder fijn als je direct met geheugen wil spelen (pointers naar pointers ed.)
verder een c++ noob, dus ga me niet slaan :+

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

defusion schreef op donderdag 17 november 2005 @ 17:04:
Ok, bedankt :)
new char werkt perfect. Ik was zelf al gaan spelen met het object string, maar dat werkt toch iets minder fijn als je direct met geheugen wil spelen (pointers naar pointers ed.)
verder een c++ noob, dus ga me niet slaan :+
C++:
1
2
std::string naam;
char* naamptr = naam.c_str();

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 01:25

GrimaceODespair

eens een tettenman, altijd ...

defusion schreef op donderdag 17 november 2005 @ 17:04:
new char werkt perfect. Ik was zelf al gaan spelen met het object string, maar dat werkt toch iets minder fijn als je direct met geheugen wil spelen (pointers naar pointers ed.)
verder een c++ noob, dus ga me niet slaan :+
Misschien weer een stomme vraag, maar waarom gaat een c++ n00b als eerste met pointers naar pointers aan de slag?

Wij onderbreken deze thread voor reclame:
http://kalders.be


  • defusion
  • Registratie: Juli 2003
  • Niet online
Zoijar schreef op donderdag 17 november 2005 @ 17:07:
[...]

C++:
1
2
std::string naam;
char* naamptr = naam.c_str();
Die had ik ook al uitgevonden ;)
maar vroeg me af waarom het nou op mijn laptop wel gewoon werkte zoals ik het had

  • defusion
  • Registratie: Juli 2003
  • Niet online
GrimaceODespair schreef op donderdag 17 november 2005 @ 17:09:
[...]

Misschien weer een stomme vraag, maar waarom gaat een c++ n00b als eerste met pointers naar pointers aan de slag?
dat was het enige voordeel dat ik zag tegenover de talen die ik wel ken, en ik bedoelde dat het string object een pointer bevat naar de werkelijke "array of chars", en ik daarover weer een pointer moest maken. Vond ik 8)7
Ik zou het alleen als een voordeel beschouwen als je d'r een nuttige toepassing voor hebt :)
Die heb ik wel, dit is ook alleen om te oefenen :)

[ Voor 36% gewijzigd door defusion op 17-11-2005 17:13 ]


  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 01:25

GrimaceODespair

eens een tettenman, altijd ...

defusion schreef op donderdag 17 november 2005 @ 17:11:
[...]

dat was het enige voordeel dat ik zag tegenover de talen die ik wel ken 8)
Ik zou het alleen als een voordeel beschouwen als je d'r een nuttige toepassing voor hebt :)

Wij onderbreken deze thread voor reclame:
http://kalders.be


  • defusion
  • Registratie: Juli 2003
  • Niet online
en over mijn verdere code:
C++:
1
2
3
4
5
6
  int *memloc;
  char *name2;
  memloc = (int *) 0x241ff5c;
  name2 = (char *) *memloc;

  cout << name2 << endl;

Kan dit beter? ik vind dit er wat raar uitzien.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-04 02:19
Wat wil je er dan mee doen?

Als je een naam wil inlezen en dan terugprinten moet je gewoon een std::string gebruiken; dat is al vaak genoeg gezegd. Als je (om te oefenen) met pointers wil klooien dan kan dit, maar in productiecode slaat het nergens op.

Ik heb het idee dat je geen idee hebt waar je mee bezig bent, geen clue hebt hoe geheugenallocatie in C/C++ werkt, en geen benul hebt van waar pointers voor dienen. De code in je TS is op praktische alle denkbare punten fout (schrijven in ongealloceerd geheugen, integers naar pointers converteren, enzovoorts).

Dus, als je een zinnig antwoord wil, vermeldt dan wat je wil bereiken, dan kunnen we je wel een methode aanraden om dat op een handige manier te doen. ;)

[ Voor 28% gewijzigd door Soultaker op 17-11-2005 17:23 ]


  • defusion
  • Registratie: Juli 2003
  • Niet online
Ik wil de "array of chars" waar 0x241ff5c (of een andere willekeurige BEKENDE locatie) naar verwijst uitlezen. En natuurlijk wil ik hetzelfde ook kunnen voor integers, doubles, etc.
Dan wil ik later ook naar deze locaties kunnen schrijven. Denk aan bijvoorbeeld trainers voor games als doeleind.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
defusion schreef op donderdag 17 november 2005 @ 17:26:
Dan wil ik later ook naar deze locaties kunnen schrijven. Denk aan bijvoorbeeld trainers voor games als doeleind.
Uhm.. Dat gaat je op die manier niet lukken hoor ;)
Die "bekende locatie" is uit je eigen memory space van je eigen proces. Je kunt niet zomaar in "andermans" geheugen schrijven hoor ;)

Zie daarvoor ReadProcessMemory en WriteProcessMemory (o.a.)

[ Voor 34% gewijzigd door RobIII op 17-11-2005 17:36 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:12

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar schreef op donderdag 17 november 2005 @ 17:07:
[...]

C++:
1
2
std::string naam;
char* naamptr = naam.c_str();
je vergeet const ;)
defusion schreef op donderdag 17 november 2005 @ 17:18:
en over mijn verdere code:
C++:
1
2
3
4
5
6
  int *memloc;
  char *name2;
  memloc = (int *) 0x241ff5c;
  name2 = (char *) *memloc;

  cout << name2 << endl;

Kan dit beter? ik vind dit er wat raar uitzien.
Als je weet dat je char array op 0x241ff5c begint, waarom doe je dan niet meteen memloc = (char*)0x241ff5c? En als dat adres de pointer naar die array bevat, doe dan *(char **)0x241ff5c. Die indirection via int is een beetje vreemd

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.


  • defusion
  • Registratie: Juli 2003
  • Niet online
RobIII schreef op donderdag 17 november 2005 @ 17:28:
[...]

Uhm.. Dat gaat je op die manier niet lukken hoor ;)
Die "bekende locatie" is uit je eigen memory space van je eigen proces. Je kunt niet zomaar in "andermans" geheugen schrijven hoor ;)

Zie daarvoor ReadProcessMemory en WriteProcessMemory (o.a.)
dat ik ga zeker eens doorlezen ;)
maar zo ver was ik nog niet, ik dacht zelf al aan een soort hook, dus zeg maar dat de "trainer" het "spel" zelf inlaad, en het als hetzelfde proces gezien word. En zo dus erin kunnen schrijven.
Magoed, zoals ik zei, dat komt nog wel :+

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...


Verwijderd

defusion schreef op donderdag 17 november 2005 @ 17:18:
en over mijn verdere code:
C++:
1
2
3
4
5
6
  int *memloc;
  char *name2;
  memloc = (int *) 0x241ff5c;
  name2 = (char *) *memloc;

  cout << name2 << endl;

Kan dit beter? ik vind dit er wat raar uitzien.
Leg eerst maar eens uit wat je wilt, waarom verwijs je keihard naar geheugenadres? Deze code slaat gewoon nergens op.
Daarbij is de volgende code:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>

int main(int argc, char* argv[])
{
  std::string name;
  std::cin >> name;
  int l = name.length();
  char* p = std::strcpy(new char[l+1], name.c_str(), l);
  std::cout << p;
  delete[] p;
}

Veel veiliger omdat je nu:
a) Zeker weet dat je voldoende geheugen hebt gealloceerd om je invoer te bevatten. Hiermee voorkom je dus buffer overflows.
b) Zeker weet dat de temporary name.c_str() niet onder je voeten wordt weggemaaid doordat je een kopietje hebt gemaakt.
c) Alsnog met je pointers aan de slag kunt al kan ik me niet bedenken wat daar in deze context het nut van is, zelfs niet als het puur om het leren gaat.
}
/Edit: had slechts pagina 1 gelezen en niet verder gekeken dan mijn neus lang was.

[ Voor 9% gewijzigd door Verwijderd op 18-11-2005 11:27 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:12

.oisyn

Moderator Devschuur®

Demotivational Speaker

Die code is niet veiliger omdat je gegarandeerd een buffer overflow introduceert (hint: regel 9 ;))

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.


Verwijderd

.oisyn schreef op vrijdag 18 november 2005 @ 11:26:
Die code is niet veiliger omdat je gegarandeerd een buffer overflow introduceert (hint: regel 9 ;))
Enlighten me, ik had in eerste instantie idd. een foutje (+1 stond verkeerd), maar hoezo kan dit in potentie een buffer overflow veroorzaken?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:12

.oisyn

Moderator Devschuur®

Demotivational Speaker

daarom dus :) Je alloceerde 1 char te weinig, en je telde er ook nog eens 1 bij de pointer op, waardoor er dus 2 chars buiten de buffer geschreven werden. Maar goed, ik snapte ook wel dat dat een foutje was ;).

Overigens heeft strcpy maar 2 parameters

[ Voor 71% gewijzigd door .oisyn op 18-11-2005 11:45 ]

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.


Verwijderd

.oisyn schreef op vrijdag 18 november 2005 @ 11:43:
daarom dus :) Je alloceerde 1 char te weinig, en je telde er ook nog eens 1 bij de pointer op, waardoor er dus 2 chars buiten de buffer geschreven werden. Maar goed, ik snapte ook wel dat dat een foutje was ;).

Overigens heeft strcpy maar 2 parameters
Tja, dat krijg je als je je code niet eerst door een compiler gooit en meteen reageert. Die laatste (2 params) twijfelde ik overigens nog over, maar inderdaad, ik had dus of de laatste param kunnen weglaten of strncpy gebruiken.
Pagina: 1