Toon posts:

[C++] pointer naar string returnen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Zoals de titel al zegt, er moet een pointer naar een string teruggegeven worden door een functie. Een heel simpel iets, maar ik zit ff vast. Soms krijg ik 0, 4, 8, of 12 tekens terug ipv gewoon de string. Dus wat gaat er hier fout?

Voor het gemak ff een simpel progje gemaakt dat dezelfde fout opleverd:
code:
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
#include <conio.h>
#include <fstream.h>

char* GetText();

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

    strcpy (tekst, GetText());

    cout << "Text: " << tekst << endl;

    getch();
    return 0;
}

char* GetText()
{
    char testText[16];

    strcpy (testText, "blaat ofzo");

    return testText;
}

Verwijderd

Bij het returnen uit de GetText functie wordt de testText char array vernietigd (bij wijze van spreken). De caller krijgt dus een 'foute' pointer terug.

Oplossingen:
- std::string oid. returnen;
- pointer naar nieuw dynamisch gealloceerde char array returnen;
- char array static maken.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

dit kan natuurlijk ook:
code:
1
2
3
4
const char * GetText ()
{
    return "blaat ofzo";
}

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.


  • Tim
  • Registratie: Mei 2000
  • Laatst online: 23-07 15:18

Tim

Verder zou ik ook eens kijken naar een nieuwe compiler

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 17 juli 2002 19:43 schreef Timpie het volgende:
Verder zou ik ook eens kijken naar een nieuwe compiler
kun je dat onderbouwen?
ik kan namelijk uit zijn openingspost niet opmaken welke compiler hij gebruikt, en of die evt te oud zou zijn of niet :?

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

Topicstarter
Tnx voor de tips, daar kom ik de avond wel mee door ;)

Btw, ik gebruik C++ builder 3. Handig voor bepaalde progjes, maar absoluut niet de meest bugvrije compiler :X

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dan zou ik ook maar eens gaan kijken naar een nieuwe compiler ;)

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

Wat ook nog kan (ik vertel het even omdat deze oplossing ook vaak wordt gebruikt):
code:
1
2
3
4
void GetText(char *MyText)
{
    strcpy (MyText, "blaat ofzo");
}

en dan aanroepen met
code:
1
2
char tekstje[16];
GetText(tekstje);

Je geeft dus in het argument de pointer mee waarin je de string "blaat ofzo" wil hebben.

  • Tim
  • Registratie: Mei 2000
  • Laatst online: 23-07 15:18

Tim

Op woensdag 17 juli 2002 19:50 schreef .oisyn het volgende:

[..]

kun je dat onderbouwen?
ik kan namelijk uit zijn openingspost niet opmaken welke compiler hij gebruikt, en of die evt te oud zou zijn of niet :?
Voor zo iets zo je toch op zijn minst een warning moeten krijgen vind ik, aangezien hij dit topic post ga ik er maar vanuit dat hij die niet krijgt

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:34
Op woensdag 17 juli 2002 20:52 schreef Shadowlaw het volgende:
Wat ook nog kan (ik vertel het even omdat deze oplossing ook vaak wordt gebruikt):
code:
1
2
3
4
void GetText(char *MyText)
{
    strcpy (MyText, "blaat ofzo");
}
En dat kan natuurlijk niet. In het algemeen zijn dergelijke constructies niet veilig (je weet immers niet altijd hoe groot je buffer moet zijn).

De correcte wijze is natuurlijk:
code:
1
2
3
4
void doe_iets(char *dst, size_t len)
{
  strncpy(dst, "w00t w00t!", len);  
}

  • risr
  • Registratie: Juli 2002
  • Laatst online: 14-07 10:19
Bekijk het volgende stukje eens (gelijk ANSI/ISO compliant 8-) - denk ik :+ )

#include <iostream>
#include <string>

using namespace std;

string GetText();

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

string text;

text = GetText();

cout << "Text: " << text
<< endl;

return 0;
}

string GetText()
{
string testText = "Jada or something!";

return testText;
}


Ik weet dat het eigenlijk over pointers ging maar zo is het toch veel makkelijker :)

Puur om te proberen. De code is niet beter ofzo.

--
Ramses
http://ramses.opweb.nl

Verwijderd

Op woensdag 17 juli 2002 21:23 schreef ramses het volgende:
Puur om te proberen. De code is niet beter ofzo.
Jawel, dat is ze wel. In jouw code wordt er maar 1x een char-array gecopieerd, in de C-style code 2x (overigens valt dat weg te optimaliseren tot 1x of zelfs 0x).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 17 juli 2002 21:07 schreef Timpie het volgende:

[..]

Voor zo iets zo je toch op zijn minst een warning moeten krijgen vind ik, aangezien hij dit topic post ga ik er maar vanuit dat hij die niet krijgt
oh? en waar moet ie de warning dan wel niet geven?
het enige wat ik zou kunnen verzinnen is dat ie <fstream.h> include ipv de extensie-loze versie, maar dat heeft totaal niets met de compiler te maken (en genereert ook lang niet altijd een warning)

De syntax is prima, staan verder geen fouten in

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

Op woensdag 17 juli 2002 22:04 schreef .oisyn het volgende:

[..]

oh? en waar moet ie de warning dan wel niet geven?
het enige wat ik zou kunnen verzinnen is dat ie <fstream.h> include ipv de extensie-loze versie, maar dat heeft totaal niets met de compiler te maken (en genereert ook lang niet altijd een warning)

De syntax is prima, staan verder geen fouten in
Hij include't <iostream> niet (voor cout).

Verder geeft mijn compiler (bc++6) de volgende warnings:
Parameter 'argc' is never used in function main(int,char * * )
Parameter 'argv' is never used in function main(int,char * * )
Suspicious pointer conversion in function GetText()
Die laatste warning gaat over het return statement in GetText, en dat is de warning die Timpie waarschijnlijk bedoelt.

Verwijderd

Op woensdag 17 juli 2002 21:22 schreef Soultaker het volgende:

[..]

En dat kan natuurlijk niet. In het algemeen zijn dergelijke constructies niet veilig (je weet immers niet altijd hoe groot je buffer moet zijn).

De correcte wijze is natuurlijk:
code:
1
2
3
4
void doe_iets(char *dst, size_t len)
{
  strncpy(dst, "w00t w00t!", len);  
}
Het kan wel. Of het verstandig is is iets anders. Het ging mij hier om het algemene idee van een dergelijke constructie te geven, niet om code te geven waar iemand buffer overflows op gaat exploiten. Bovendien zijn er andere manieren om die lekken te voorkomen dan jouw len parameter - maar dat is allemaal offtopic.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
Op woensdag 17 juli 2002 22:04 schreef .oisyn
De syntax is prima, staan verder geen fouten in
Ik meende ooit een compiler gebruikt te hebben die het returnen van een pointer naar een stack var ook als warning aangaf, alhoewel ik niet meer weet welke dat was.

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.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op woensdag 17 juli 2002 21:57 schreef mietje het volgende:

[..]

Jawel, dat is ze wel. In jouw code wordt er maar 1x een char-array gecopieerd, in de C-style code 2x (overigens valt dat weg te optimaliseren tot 1x of zelfs 0x).
Ik zat zelf te twijfelen tussen 2 en 3 kopieen. Hoe kom jij aan 1?

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


Verwijderd

Op donderdag 18 juli 2002 10:05 schreef MSalters het volgende:
Ik zat zelf te twijfelen tussen 2 en 3 kopieen. Hoe kom jij aan 1?
Volgens mij wordt er alleen een char array gekopieerd bij het assignment string testText = "Jada or something!";. Er worden verder geen methodes aangeroepen die de string selfish maken, dus zou de originele representatie gepropageerd moeten worden.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op donderdag 18 juli 2002 12:24 schreef mietje het volgende:

[..]

Volgens mij wordt er alleen een char array gekopieerd bij het assignment string testText = "Jada or something!";. Er worden verder geen methodes aangeroepen die de string selfish maken, dus zou de originele representatie gepropageerd moeten worden.
Shared string representaties zijn zo nineties. Welkom in deze eeuw :)

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


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op donderdag 18 juli 2002 14:39 schreef MSalters het volgende:
Shared string representaties zijn zo nineties. Welkom in deze eeuw :)
Wat bedoel je hiermee? Is de handling van (std::) string dan zo gewijzigd?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op woensdag 17 juli 2002 21:07 schreef Timpie het volgende:

Voor zo iets zo je toch op zijn minst een warning moeten krijgen vind ik, aangezien hij dit topic post ga ik er maar vanuit dat hij die niet krijgt
Een OW? Hij heeft geen void main() gebruikt hoor ;)

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


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op donderdag 18 juli 2002 15:01 schreef Orphix het volgende:

[..]

Wat bedoel je hiermee? Is de handling van (std::) string dan zo gewijzigd?
De implementatie is veranderd. Je zou het niet moeten merken, afgezien van performance, als std::string z'n chars kopieert. char heeft tenslotte geen ctor/dtor.
Het bleek eenvoudiger te zijn de strings gewoon te kopieren; de shared string check bleek te duur.
Elke potentiele operatie die de string kon veranderen, zoals string::operator[], moest de bit checken. operator[] werd natuurlijk nogal eens in een loop gebruikt. Aangezien nieuwe string implementaties ook nog de small string optimalisatie gebruiken is die kopie sneller gemaakt.

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


Verwijderd

Op donderdag 18 juli 2002 14:39 schreef MSalters het volgende:
Shared string representaties zijn zo nineties. Welkom in deze eeuw :)
:) Wijs mij eens een STL aan die basic_string niet met gescheiden representaties implementeert?

Uit de SGi spec:
Note that the C++ standard does not specify the complexity of basic_string operations. In this implementation, basic_string has performance characteristics very similar to those of vector: access to a single character is O(1), while copy and concatenation are O(N). By contrast, rope has very different performance characteristics: most rope operations have logarithmic complexity.

Note also that, according to the C++ standard, basic_string has very unusual iterator invalidation semantics. Iterators may be invalidated by swap, reserve, insert, and erase (and by functions that are equivalent to insert and/or erase, such as clear, resize, append, and replace). Additionally, however, the first call to any non-const member function, including the non-const version of begin() or operator[], may invalidate iterators. (The intent of these iterator invalidation rules is to give implementors greater freedom in implementation techniques.) In this implementation, begin(), end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators. In this implementation, iterators are only invalidated by member functions that explicitly change the string's contents.
Ik interpreteer deze iterator-semantiek als de mogelijkheid voor basic_string om op veel verschillende manieren geimplementeerd te worden. Maar zoals al gezegd, ik ken alleen basic_string::reps met copy-on-demand implementaties, behalve die van SGi.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op donderdag 18 juli 2002 15:32 schreef mietje het volgende:

[..]

:) Wijs mij eens een STL aan die basic_string niet met gescheiden representaties implementeert?

Uit de SGi spec:
[..]

Ik interpreteer deze iterator-semantiek als de mogelijkheid voor basic_string om op veel verschillende manieren geimplementeerd te worden. Maar zoals al gezegd, ik ken alleen basic_string::reps met copy-on-demand implementaties, behalve die van SGi.
'k snap je verhaal niet. Je vraagt eerst om een STL die wel met shared representations werkt, en daarna zeg je dat afgezien van SGI iedereen shared representations aka copy-on-demand gebruiken. Dus dan kan ik iedereen aanwijzen behalve SGI :?

Maar MSVC is waarschijnlijk een goed voorbeeld hier. VC6 had default een shared-string, VC7 niet, en mijn gehackte VC6 ook niet meer.(8>

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


Verwijderd

Op donderdag 18 juli 2002 16:44 schreef MSalters het volgende:
'k snap je verhaal niet. Je vraagt eerst om een STL die wel met shared representations werkt, en daarna zeg je dat afgezien van SGI iedereen shared representations aka copy-on-demand gebruiken. Dus dan kan ik iedereen aanwijzen behalve SGI :?
Ik vraag om een implementatie die niet met shared reps werkt, en geef zelf al aan dat de SGi implementatie de enige is die ik ken die geen shared reps gebruikt. MSVC 7.0 dus blijkbaar ook.

Ik quote de tekst van SGi om aan te geven dat het al-dan-niet gebruik van copy-on-demand niet verplicht is volgens de standaard, maar dat de standaard wel alle voorwaarden schept voor een copy-on-demand implementatie.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Op woensdag 17 juli 2002 22:04 schreef .oisyn het volgende:

[..]

oh? en waar moet ie de warning dan wel niet geven?
het enige wat ik zou kunnen verzinnen is dat ie <fstream.h> include ipv de extensie-loze versie, maar dat heeft totaal niets met de compiler te maken (en genereert ook lang niet altijd een warning)

De syntax is prima, staan verder geen fouten in
Het returnen van een pointer naar een object dat vernietigd wordt.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op donderdag 18 juli 2002 21:16 schreef OlafvdSpek het volgende:

[..]

Het returnen van een pointer naar een object dat vernietigd wordt.
ja ik had het al gezien, was even in de war met een char * die gereturned werd (wat natuurlijk wel kan :))

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

Hebben jullie hier met z'n allen iets tegen malloc en free of zo....

void main(void)
{
char *st;
st = getString();
printf("%s",st);
free(st);
}

char* getString(void)
{
char *st = malloc(20*sizeof(char));
st = "hallo";
return st;
}

Simpel zat.

Verwijderd

Op vrijdag 19 juli 2002 13:41 schreef tafkam het volgende:
Hebben jullie hier met z'n allen iets tegen malloc en free of zo....
Op zich heb ik niet echt iets tegen dynamisch gealloceerd geheugen, maar ik zou het nooit met malloc en free (de)alloceren. Als ik al dynamisch geheugen nodig heb, is het in 95% van de gevallen het beste om dat geheugen door een STL container te laten beheren. Voor de overige gevallen zijn er new en delete, de verbeterde C++ versies van malloc en free.
void main(void)
Main return't een int.
char *st = malloc(20*sizeof(char));
st = "hallo";
*Ouch*. Met st="hallo" kopieer je niet de "hallo" literal naar de dynamisch gealloceerde buffer, maar reassign je simpelweg st zodat 'ie naar de static literal verwijst. Je hebt nu dus een memory leak (want de pointer naar het dynamisch gealloceerde geheugen ben je kwijt), en de call naar free vanuit main gaat mislukken (op mijn bak crasht het programma daardoor). Verder zou de return value van die malloc call volgens mij ook expliciet gecast moeten worden van een void* naar een char*.
Simpel zat.
Kennelijk niet dus. |:(


Edit. Eerste paragraaf herschreven.

Verwijderd

Op vrijdag 19 juli 2002 15:20 schreef Sneechy het volgende:

Main return't een int.
Zeik niet.

Verwijderd

Op vrijdag 19 juli 2002 15:20 schreef Sneechy het volgende:
Op zich heb ik niet echt iets tegen dynamisch gealloceerd geheugen, maar ik zou het nooit met malloc en free (de)alloceren.
New/Delete geeft je niet de mogelijkheid om je gealloceerde geheugen te resizen. Malloc/Free/Resize wel.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op vrijdag 19 juli 2002 17:44 schreef vicz het volgende:

[..]

Zeik niet.
reageer normaal of reageer niet
Op vrijdag 19 juli 2002 17:57 schreef vicz het volgende:

[..]

New/Delete geeft je niet de mogelijkheid om je gealloceerde geheugen te resizen. Malloc/Free/Resize wel.
zie:
Op vrijdag 19 juli 2002 15:20 schreef Sneechy het volgende:

Als ik al dynamisch geheugen nodig heb, is het in 95% van de gevallen het beste om dat geheugen door een STL container te laten beheren.

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

Op vrijdag 19 juli 2002 18:03 schreef .oisyn het volgende:
zie:

Als ik al dynamisch geheugen nodig heb, is het in 95% van de gevallen het beste om dat geheugen door een STL container te laten beheren.
Hoe denk je dat ze dat in STL hebben geimplementeerd?
Om maar even te zwijgen over het feit, dat de S van Standard niet op alle platform het zelfde betekent.

Verwijderd

Op vrijdag 19 juli 2002 18:03 schreef .oisyn het volgende:
reageer normaal of reageer niet
Oh Sorry hoor liet mij even gaan... dat was een totale offtopic opmerking van Sneechy.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op vrijdag 19 juli 2002 18:08 schreef vicz het volgende:

[..]

Hoe denk je dat ze dat in STL hebben geimplementeerd?
niet met malloc/resize/free
kan ook niet, omdat je nou eenmaal niet zomaar de data binair kunt kopieren... je hebt te maken met (copy)constructors, destructors en assignment operators die aangeroepen moeten worden (er kunnen tenslotte ook andere typen dan primitieven in staan). Dat is trouwens ook de hele reden waarom er geen resize variant bestaat
Op vrijdag 19 juli 2002 18:11 schreef vicz het volgende:

[..]

Oh Sorry hoor... dat was een totaal offtopic opmerking van jou... (zo goed?)
die begrijp ik niet helemaal (FYI: ik ben niet Sneechy, de persoon waarop je reageerde)

PS. er bestaat trouwens zo'n mooi edit-knopje (Afbeeldingslocatie: http://gathering.tweakers.net/global/templates/tweakers/images/icons/edit.gif) waarmee je je bericht kunt wijzigen en er dus ook wat achter kunt plakken

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

Op vrijdag 19 juli 2002 18:13 schreef .oisyn het volgende:

[..]

niet met malloc/resize/free
kan ook niet, omdat je nou eenmaal niet zomaar de data binair kunt kopieren... je hebt te maken met (copy)constructors, destructors en assignment operators die aangeroepen moeten worden (er kunnen tenslotte ook andere typen dan primitieven in staan). Dat is trouwens ook de hele reden waarom er geen resize variant bestaat
Nou... de STL library die ik hier heb, gebruikt uiteindelijk altijd malloc/free.
die begrijp ik niet helemaal (FYI: ik ben niet Sneechy, de persoon waarop je reageerde)
Sorry for that.

Verwijderd

Op vrijdag 19 juli 2002 18:13 schreef .oisyn het volgende:
niet met malloc/resize/free
kan ook niet, omdat je nou eenmaal niet zomaar de data binair kunt kopieren... je hebt te maken met (copy)constructors, destructors en assignment operators die aangeroepen moeten worden (er kunnen tenslotte ook andere typen dan primitieven in staan).
Destructors kunnen direct aangeroepen worden, en met een new expressie kun je optioneel geheugen aanwijzen waar het object aangemaakt moet worden. Een lijst van objecten van type T bijhouden in bijvoorbeeld een char buffer is op deze manier wel mogelijk. Zie voor meer informatie en een uitgewerkt voorbeeld Item 12 uit 'Exceptional C++' van Herb Sutter.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op vrijdag 19 juli 2002 19:10 schreef Sneechy het volgende:

[..]

Destructors kunnen direct aangeroepen worden, en met een new expressie kun je optioneel geheugen aanwijzen waar het object aangemaakt moet worden. Een lijst van objecten van type T bijhouden in bijvoorbeeld een char buffer is op deze manier wel mogelijk.
klopt idd, maar dan kun je nog niet zomaar een buffer heralloceren met resize door simpelweg alle data bitwise te kopieren. (vandaar dat ik zei dat de constructors en destructors aangeroepen moesten worden... ik zei verder niet dat dat per se met new T of delete moest gebeuren)

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.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op vrijdag 19 juli 2002 18:46 schreef vicz het volgende:

[..]

Nou... de STL library die ik hier heb, gebruikt uiteindelijk altijd malloc/free.
maar geen resize :)

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.


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 21-06 17:10
De fout in je code zit 'm hierin:
Je geeft aan dat je een char * wilt returnen, maar je gaat een char[] teruggeven! <onjuist>
Waarschijnlijk werkt het wel als je return testText[0] doet. Want een pointer naar een character array is altijd gelijk aan het adres van het eerste element :P <wel juist, maar verkeerd uitgelegd. testText is juist goede adres>
Wanneer je dit niet mooi vind, kan je ook in de functie niet een character array, maar gewoon char * aanmaken. Bij strcpy wordt er dan automatisch ruimte voor gereserveerd. <onjuist> Dan kan je gewoon return testText doen.

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


Verwijderd

Op vrijdag 19 juli 2002 20:10 schreef riezebosch het volgende:
De fout in je code zit 'm hierin:
Je geeft aan dat je een char * wilt returnen, maar je gaat een char[] teruggeven!
Dat is het probleem niet, zie mijn eerste reply voor wat wel het probleem is.
Bij strcpy wordt er dan automatisch ruimte voor gereserveerd.
strcpy alloceert geen geheugen (!).

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 21-06 17:10
sorry, je hebt inderdaad gelijk.
en dat van tempText[0] klopt ook niet, want juist tempText is het adres waar een pointer naar moet verwijzern.

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op vrijdag 19 juli 2002 20:26 schreef Sneechy het volgende:

strcpy alloceert geen geheugen (!).
strdup echter wel :)

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

Sneency je moet niet al te hard lopen miepen hoor. Het ging over het idee van het gebruik van malloc en free.
I.p.v. het gebruik van '=' had ik natuurlijk strcpy moeten gebruiken. |:( (helemaal waar)

Tsja, het is al weer duidelijk dat ik geen hardcore c'er ben. Kou me meer bezig met assembly (in combinatie met C) en VBA. Een combinatie van beide maakt me wel eens in de war. :?
Dus ik zal voortaan maar mijn mond houden in dit soort threads. (veroorzaakt alleen maar veel te velle discussies) :P

Vriendelijke groet,
Arnold

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 19 juli 2002 15:20 schreef Sneechy het volgende:
Verder zou de return value van die malloc call volgens mij ook expliciet gecast moeten worden van een void* naar een char*.
[..]
Dat is een van de weinige verschillen tussen C en C++, en dag is het nog voornamelijk conventie. In C moet je niet casten; als malloc niet gedefinieerd is krijg je dan een int->char* warning. In C++ moet je wel casten; als malloc niet gedefinieerd is krijg je toch wel een error, en zonder de cast heb je ook een type error.

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


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 19 juli 2002 19:57 schreef .oisyn het volgende:

[..]

... ik zei dat de constructors en destructors aangeroepen moesten worden... ik zei verder niet dat dat per se met new T of delete moest gebeuren
Maar om een object in zo'n char[] buffer te zetten heb je dus wel new nodig, placement new om precies te zijn.

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


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
Op zaterdag 20 juli 2002 13:15 schreef tafkam het volgende:
Dus ik zal voortaan maar mijn mond houden in dit soort threads. (veroorzaakt alleen maar veel te velle discussies) :P
Een felle discussie is niet verkeerd, het is echter wel belangrijk dat je beleefd blijft in die discussie.

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.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op maandag 22 juli 2002 09:54 schreef MSalters het volgende:

[..]

Maar om een object in zo'n char[] buffer te zetten heb je dus wel new nodig, placement new om precies te zijn.
vandaar dat ik zei new T, niet new (ptr) T :)
Maar dat is het hele punt niet, waar het om ging is dat je resize niet kunt gebruiken om een buffer zomaar te resizen... je hebt namelijk tijdelijk 2 buffers nodig: de oude en de nieuwe. Zodra je de nieuwe hebt aangemaakt moet je voor de elementen die gekopieerd moeten worden de copy-constructor aanroepen in de nieuwe buffer en de destructor in de oude buffer (en dan nog wat destructors in de oude buffer als de nieuwe buffer kleiner is, of wat constructors in de nieuwe buffer als de nieuwe buffer groter is). En vervolgens geef je de oude buffer weer vrij.

Als je dat met resize gaat doen worden de (copy)constructors en destructors dus helemaal niet aangeroepen, vandaar mijn reactie dat realloc niet te gebruiken is (hmm ik zie nu trouwens dat we het de hele tijd over resize hadden... dat moet dus realloc zijn :))

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.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op maandag 22 juli 2002 12:12 schreef .oisyn het volgende:
Maar dat is het hele punt niet, waar het om ging is dat je resize niet kunt gebruiken om een buffer zomaar te resizen... je hebt namelijk tijdelijk 2 buffers nodig: de oude en de nieuwe. Zodra je de nieuwe hebt aangemaakt moet je voor de elementen die gekopieerd moeten worden de copy-constructor aanroepen in de nieuwe buffer en de destructor in de oude buffer (en dan nog wat destructors in de oude buffer als de nieuwe buffer kleiner is, of wat constructors in de nieuwe buffer als de nieuwe buffer groter is). En vervolgens geef je de oude buffer weer vrij.
Dat is alleen het geval als er een nieuw geheugenadres gealloceerd wordt. Als het bestaande blok vergroot kan worden is dat niet nodig. Ik dacht dat Linux realloc dat al deed; ik weet't niet van STL implementaties (afgezien van de verplichte reserve() methodes). Dat is overigens een van de betere redenen voor 64bits CPUs, zodat je na elke alloc een facto 64 ruimte kunt laten voor nieuwe reallocs waarbij het adres niey wijzigt.

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op maandag 22 juli 2002 15:58 schreef MSalters het volgende:

[..]

Dat is alleen het geval als er een nieuw geheugenadres gealloceerd wordt. Als het bestaande blok vergroot kan worden is dat niet nodig.
daar heb je natuurlijk helemaal gelijk in, maar het is een beetje onzin om per allocatie van minder dan 4k een hele 4k page te reserveren, alleen maar zodat je het later uit kunt breiden. Imho kan realloc die garantie gewoon niet geven

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

Als het goed begrijp komt het op het volgende neer:
*er is een functie nodig die een waarde in een char* zet.
*dit moet ongeveer zo gebeuren:
-je declareerd een variable
-je initialiseerd hem (alloceerd geheugen in dit geval)
-je copieerd de waarde erin.

hoe je dat precies doet, is nogal wat onenigheid over op dit forum, maar dat maakt toch helemaal niet uit ?? als ie het maar doet.

om toch ook ff mee te doen, volgens mij is dit een makkelijke oplossing:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
typedef unsigned int dword;
typedef bool       err;

err copy_string(char *&amp;dest, char *source)
{
  dword size;
  for(size = 0; source[size]; size++);
  if(!size)                      // dan valt er niets te copieren
    return 0;

  if(!dest)
    if(!mem_alloc((void *&amp;)dest), size + 1))  // vergeet de NULL niet (NULL-terminated-string)
    return 0;                    // allocatie gaat hier fout, hoe die dat doet,
                                // zoeken jullie zelf maar uit :-)
  for(dword n = 0; n &lt; size; n++)
    dest[n] = source[n];
  return 1;
}

edit:

oeps... laatste regel vergeten :-)

Verwijderd

Beetje wazig dat je retouneerd met een error (return 0) als de size van de string 0 is. Alloceer gewoon 1 byte geheugen en zet daar een 0 character in.
Het is en blijft een copy functie!

edit: je functie levert ook nog eens een warning op: function should return a value.

Verwijderd

yep... kwestie van smaak.
als er niet geen characters te copieren zijn, dan moet ie ook geen geheugen ervoor alloceren (vind ik).
zoals ik al zei... kwestie van smaak :-)

Verwijderd

Op dinsdag 23 juli 2002 15:17 schreef Jappie wat code
Dit is ongeveer wat std::strdup (8 posts geleden door .oisyn aangekaart) doet (maar strdup doet het zonder fouten..) :).

Verwijderd

haha... kan best, zoals ik al zei bebruik ik weinig bestaande libraries (alleen als er echt geen zin in heb :-)

maaruhh... fouten ??
ik heb hier geen compiler bij de hand, maar dit zou het echt moeten doen...

Verwijderd

Op dinsdag 23 juli 2002 16:30 schreef Jappie het volgende:
maaruhh... fouten ??
- een unsigned int is niet altijd een dword
- een imho overbodige typedef voor err
- unsigned int is niet de meest ideale keuze voor je counters
- char * source moet const char * source zijn
- dat wat unteraarsch al noemde beschouw ik als een ernstige fout
- gebruik van return code ipv. exception
- het niet gebruiken van std::strlen e.d.
- een imho overbodige if(!dest)
- geen else-clause voor je if(!dest)
- het gebruik van mem_alloc in plaats van een standaard functie
Een aantal genoemde zaken is puur persoonlijke mening
ik heb hier geen compiler bij de hand, maar dit zou het echt moeten doen...
Programmeren is meer dan zorgen dat het compiled :+.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op dinsdag 23 juli 2002 16:30 schreef Jappie het volgende:
...zoals ik al zei gebruik ik weinig bestaande libraries
...
maaruhh... fouten ??
Dat zijn twee zinnen die IMO met elkaar in tegenspraak zijn. Een library functie herschrijven kan het aantal bugs in je programma alleen verhogen, het geheugengebruik verhogen, de cache hit ratio verlagen en de onderhoudbaarheid ook verlagen. Kortom, tijd voor de cluebat. :)

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


Verwijderd

dat kan ja...
het kan ook het tegenovergestelde doen...
ander voordeel is dat je precies weet wat er gebeurd in je source...

maarja... dit hele topic draait eigenlijk om persoonlijke smaak, zullen we het daar maar bij laten :)
Pagina: 1