Ho il seguente problema: Sto scrivendo un programma C++ che deve avvolgere una libreria C, quindi quando interagisco con la libreria devo sempre usare char*
invece di std::string
per tutte le operazioni. Al fine di evitare di lavorare con char*
quanto possibile, faccio la formattazione con stringstreams, per esempio come questo:strdup con stringstreams causa errori valgrind
#include <iostream>
#include <sstream>
#include <string.h>
#include <cstdlib>
using namespace std;
int main(int argc, char** argv)
{
ostringstream str;
str << argv[0] << "+" << "hello";
const char *s = str.str().c_str();
char *y = strdup(s);
// this I would give to a library function
cout << y << endl;
free(y);
return 0;
}
quanto riguarda l'uscita passa, il programma emette correttamente "./test+hello". Tuttavia, Valgrind mi dà un sacco di errori di tipo
==30350== Invalid read of size 1
==30350== at 0x402B858: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==30350== by 0x4213475: strdup (in /usr/lib/libc-2.16.so)
==30350== by 0x41B2604: (below main) (in /usr/lib/libc-2.16.so)
==30350== Address 0x4341274 is 12 bytes inside a block of size 25 free'd
==30350== at 0x4029F8C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==30350== by 0x410387A: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.17)
==30350== by 0x41B2604: (below main) (in /usr/lib/libc-2.16.so)
Che cosa sto facendo di sbagliato?
Funzionerebbe in tutti i casi se scriveste 'char * y = strdup (str.str(). C_str());'? –
Sì, funzionerebbe anche - copiando la stringa prima che la sua memoria sia cancellata e non mantenendo una copia del puntatore in seguito. – jcoder
@JonasWielicki Sì. La durata del temporaneo è fino alla fine dell'espressione completa. (In realtà preferirei qualcosa di succinto come questo, ma le opinioni variano. Non vuoi introdurre molte variabili intermedie non necessarie, ma non vuoi che le espressioni siano troppo complicate. su chi chiedi.) –