Avatar billede petermjensen Nybegynder
07. september 2007 - 10:35 Der er 9 kommentarer og
2 løsninger

char til string - rydde op

Hej Eksperter :)

Jeg sidder lige og leger lidt med at konverterer char* til en std::string men jeg er kommet lidt i tvivl om hvordan std::string rydder op efter sig selv.

Hvis man gøre f.eks som nedenstående:
char* buffer = (char*)malloc(size);
std::string str(buffer);

Hvordan bliver buffer free'ed?

Min umiddelbare idé er at free buffer efter at laved str, da jeg syntes at læse at std::string har en copy constructor. Så ville jeg mene at den laver en kopi af buffer og derefter ville det være muligt at rydde op.
Men det kan man ikke. For så er bliver strengens data væk?

Hvordan ryder man op efter ovenstående?
Avatar billede intel4004 Novice
07. september 2007 - 19:32 #1
http://www.cppreference.com/cppstring/string_constructors.html

Den string constructor som modtager en const char* skulle meget gerne oprette sit eget hukommelses område og kopiere C-strengens bytes fra adressen og indtil den termineres med '\0'. Det er jeg faktisk sikker på at den gør da en STL klasses interne state meget usandsynligt er afhængig af en "fremmed pointer" (i dit eksempel din char* buffer).

Dette her fungerer fint hos mig:

#include <iostream>
#include <string>
#include <conio.h>

using namespace std;

int main()
{
  char* buf = (char*)malloc(5);
 
  buf[0] = 'h';
  buf[1] = 'a';
  buf[2] = 'l';
  buf[3] = 'l';
  buf[4] = 'o';
 
  string str(buf);
 
  free(buf);
 
  cout << str;
 
  getch();
}

Hvilken compiler bruger du?

Mvh Intel4004
Avatar billede intel4004 Novice
07. september 2007 - 19:47 #2
Hmm, jeg burde måske have gjort sådan:

...

char* buf = (char*)malloc(6);

buf[0] = 'h';
buf[1] = 'a';
buf[2] = 'l';
buf[3] = 'l';
buf[4] = 'o';
buf[5] = '\0';

...

Er nok mere korrekt hvis det nu skal være. Men det giver nu ingen forskel.

Mvh Intel4004
Avatar billede arne_v Ekspert
08. september 2007 - 04:42 #3
Eksemplet er ikke godt, da free jo ikke kan forventes at overskrive memory - memory
bliver kun markeret til genbrug.

Men:

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main()
{
    char buf[] = "Hello";
    string s(buf);
    strcpy(buf, "world");
    cout << s << endl;
    return 0;
}

skriver altså "Hello" og ikke "world", så jeg er helt enig i konklusionen, at string
constructor laver en kopi.
Avatar billede petermjensen Nybegynder
09. september 2007 - 13:57 #4
intel4004: Jeg bruger gcc på linux (4.1.2)
Det er godt nok underligt.
Hvis jeg prøver intel4004's test får jeg en coredump lisså snart buf bliver free'd.
Jeg har prøvet arne_v's test, og den giver det rigtige resultat('hello').

Er det ikke underligt?
For hvis det ikke kan lade sig gøre, så vil der opstå en masse mem leaks :)
Avatar billede intel4004 Novice
09. september 2007 - 14:37 #5
Det lyder umiddelbart mystisk. Jeg har dog kun forsøgt på Windows XP med MinGW/GCC 3.4.5.

Hvorfor bruger du malloc() i C++ til dynamisk allokering? new bør vel egentligt bruges? Men alligevel kan jeg ikke se hvorfor det ikke burde virke.

En fejl i GCC 4.1.2? Jeg har en dårlig vane hvor jeg mistænker compileren før jeg mistænker mig selv :)

Mvh Intel4004
Avatar billede intel4004 Novice
09. september 2007 - 14:54 #6
Altså sådan her:

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main()
{
    char* buf = new char [6];
    strcpy(buf, "hallo");
   
    string s(buf);
    delete[] buf;
   
    cout << s << endl;
   
    return 0;
}

Bemærk også at jeg benytter conio.h og et kald til getch() i mit tidligere eksempel. Det gør det nemmere at teste på windows.
Avatar billede arne_v Ekspert
09. september 2007 - 22:53 #7
Jeg har lige testet på min Linux med GCC 4.1.1 og ingen af programmerne:
  07/09-2007 19:47:55
  08/09-2007 04:42:22
  09/09-2007 14:54:32
fejler ...
Avatar billede petermjensen Nybegynder
10. september 2007 - 20:37 #8
Undskyld forsinkelsen, men jeg måtte lige prøve på en maskine på arbejdet. Præcis samme kode.
Præcis samme gcc. (dog lidt nyere distribution).
Og jeg fik samme resultat som jer.
Det syntes jeg godt nok er underligt.

Men pyt skidt. jeg har lært en del, så i skal have tak for hjælpen!
Kan jeg få jer til at lægge et svar?

intel4004: "En fejl i GCC 4.1.2? Jeg har en dårlig vane hvor jeg mistænker compileren før jeg mistænker mig selv :)"
Sådan en vane har jeg osse lige fået :)
Avatar billede intel4004 Novice
10. september 2007 - 22:27 #9
...et svar.

hehe, det er egentlig en dårlig vane at få. Men min endelige konklusion har indtil videre, altid været den, at det er mig som laver fejl, og ikke gcc :)

Mvh Intel4004
Avatar billede arne_v Ekspert
11. september 2007 - 02:00 #10
svar
Avatar billede petermjensen Nybegynder
12. september 2007 - 16:27 #11
Tak skal i ha'!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester