memory allocation of char array - c++

I have following code:
Document document;
char *buf = new char[str.size()+1];
buf[str.size()] = '\0';
memcpy(buf, str.c_str(), str.size());
//string parsing
if (document.ParseInsitu<0>(buf).HasParseError()) {
cerr << "Failed to parse string ";
}
delete[] buf;
When I check the program with valgrind I get this:
==29765== Invalid read of size 1
==29765== at 0x402A682: bcmp (mc_replace_strmem.c:679)
==29765== Address 0x49626a2 is 2 bytes inside a block of size 214 free'd
==29765== at 0x402759B: operator delete[](void*) (vg_replace_malloc.c:409)
==29765== Invalid read of size 1
==29765== at 0x402901A: strlen (mc_replace_strmem.c:282)
==29765== by 0x41ABE4A: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==29765== Address 0x49626a8 is 8 bytes inside a block of size 214 free'd
==29765== at 0x402759B: operator delete[](void*) (vg_replace_malloc.c:409)
==29765== Invalid read of size 1
==29765== at 0x4029D0E: memcpy (mc_replace_strmem.c:635)
==29765== by 0x41ABD15: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==29765== by 0x41ABE65: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==29765== by 0x2C23: ???
==29765== Address 0x49626b2 is 18 bytes inside a block of size 214 free'd
==29765== at 0x402759B: operator delete[](void*) (vg_replace_malloc.c:409)
what am I doing wrong?

buf[json.size()] = '\0';
isn't this supposed to be:
buf[str.size()] = '\0';
?

The problem was that I was deallocating buf too early. I supposed that the parser will make a copy of the input, which was obviously wrong.

Related

valgrind memory access error when accessing result of string::c_str()

So I was writing some networking code when I ran into the strangest memory issue and I cant properly sort out what might be going on here. I am wondering if there might be some sort of implication in c_str() that I am not properly observing.
So here is the code with the error in it. (There is also a freeing error but I made this function as just a pet project).
#include <netdb.h> // for AF_UNSPEC, AF_INET, AF_INET6
#include <stdint.h> // for uint16_t, etc.
#include <sys/types.h> // for AF_UNSPEC, AF_INET, AF_INET6
#include <sys/socket.h> // for AF_UNSPEC, AF_INET, AF_INET6
#include <string> // for std::strin
#include <stdio.h>
#include <string.h>
int main() {
uint16_t port = 2098;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET6; // IPv6 (also handles IPv4 clients)
hints.ai_socktype = SOCK_STREAM; // stream
hints.ai_flags = AI_PASSIVE; // use wildcard "INADDR_ANY"
hints.ai_protocol = IPPROTO_TCP; // tcp protocol
hints.ai_canonname = nullptr;
hints.ai_addr = nullptr;
hints.ai_next = nullptr;
const char* port_num = (std::to_string(port)).c_str();
struct addrinfo *result;
int res = getaddrinfo(nullptr, port_num, &hints, &result);
printf("HI\n");
}
If you valgrind the resulting binary you get:
==45919== Invalid read of size 1
==45919== at 0x573BA5C: getaddrinfo (in /usr/lib64/libc-2.17.so)
==45919== by 0x400C95: main (in /homes/iws/kieruc/Coding/a.out)
==45919== Address 0x5a22058 is 24 bytes inside a block of size 29 free'd
==45919== at 0x4C2B16D: operator delete(void*) (vg_replace_malloc.c:576)
==45919== by 0x4EF3B62: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib64/libstdc++.so.6.0.19)
==45919== by 0x400C7C: main (in /homes/iws/kieruc/Coding/a.out)
==45919== Block was alloc'd at
==45919== at 0x4C2A1E3: operator new(unsigned long) (vg_replace_malloc.c:334)
==45919== by 0x4EF3A18: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.19)
==45919== by 0x400FFE: char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400F14: char* std::string::_S_construct_aux<char*>(char*, char*, std::allocator<char> const&, std::__false_type) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400EDD: char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400E8F: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400E20: std::string __gnu_cxx::__to_xstring<std::string, char>(int (*)(char*, unsigned long, char const*, __va_list_tag*), unsigned long, char const*, ...) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400CDE: std::to_string(int) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400C60: main (in /homes/iws/kieruc/Coding/a.out)
==45919==
==45919== Invalid read of size 1
==45919== at 0x573BACA: getaddrinfo (in /usr/lib64/libc-2.17.so)
==45919== by 0x400C95: main (in /homes/iws/kieruc/Coding/a.out)
==45919== Address 0x5a22058 is 24 bytes inside a block of size 29 free'd
==45919== at 0x4C2B16D: operator delete(void*) (vg_replace_malloc.c:576)
==45919== by 0x4EF3B62: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib64/libstdc++.so.6.0.19)
==45919== by 0x400C7C: main (in /homes/iws/kieruc/Coding/a.out)
==45919== Block was alloc'd at
==45919== at 0x4C2A1E3: operator new(unsigned long) (vg_replace_malloc.c:334)
==45919== by 0x4EF3A18: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.19)
==45919== by 0x400FFE: char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400F14: char* std::string::_S_construct_aux<char*>(char*, char*, std::allocator<char> const&, std::__false_type) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400EDD: char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400E8F: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400E20: std::string __gnu_cxx::__to_xstring<std::string, char>(int (*)(char*, unsigned long, char const*, __va_list_tag*), unsigned long, char const*, ...) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400CDE: std::to_string(int) (in /homes/iws/kieruc/Coding/a.out)
==45919== by 0x400C60: main (in /homes/iws/kieruc/Coding/a.out)
However if I change the code to this
std::string portstr = std::to_string(port);
struct addrinfo *result;
int res = getaddrinfo(nullptr, portstr.c_str(), &hints, &result);
Then there are no memory errors. And I dont quite understand why.
Another thing to note is that if I try to compile the version with the const char* variable with char* instead you get a warning that the variable should be constant.
What is going on here?
The buffer returned by c_str is valid only as long as the associated std::string object lives. And here
const char* port_num = (std::to_string(port)).c_str();
A temporary string object is created, its buffer address is taken, and then it dies at the end of the full expression. You get a memory error for using a dangling pointer.
If you wish to use a temporary std::string, it must be created during the full expression where you use the buffer:
int res = getaddrinfo(nullptr, std::to_string(port).c_str(), &hints, &result)
With const char* port_num = (std::to_string(port)).c_str();, you are creating a temporary object of type std::string, which will live just as long as the expression in which it is used. So the .c_str() will point to memory that will get freed right after your statement.
Make two lines out of it:
auto portStr = std::to_string(port);
const char* port_num = portStr.c_str();
Thereby, the portStr-object will live until the end of the function, and you may use the result of the .c_str-call right until the end of the function (unless you alter protStr in between).

C++, Valgrind reporting "possibly lost" after char* to std::string "conversion"

I have a class with a constructor like,
Foo::Foo(string p) {
path = p;
}
And I use it like this,
Foo foo = Foo("/tmp/foo");
Sorry for my C++ naivety. I understand that this is creating a std::string object implcitly (what's the right terminology for what's going on here?).
This causes Valgrind to complain as such,
==28188== 66 bytes in 1 blocks are possibly lost in loss record 3 of 5
==28188== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28188== by 0x4EFBF28: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFD9B4: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDDDB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EC2B05: std::logic_error::logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EC5AA8: std::__throw_logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDA38: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDDDB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4022F3: main (main.cpp:13)
==28188==
==28188== 144 bytes in 1 blocks are possibly lost in loss record 4 of 5
==28188== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28188== by 0x4E9FF9F: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EC5A92: std::__throw_logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDA38: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDDDB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4022F3: main (main.cpp:13)
It looks like ultimately the "conversion" (sorry again) new'ing a std::string.
If I change my code to this,
string d = string("/tmp");
Foo Foo = Foo(d);
Valgrind does not report the leak.
This is really a leak, right? Seems like it.
What's the proper idiom to do what I'm doing here? I want the call semantics to be able to pass a char* but internally I want the class member to be a std::string.
The Valgrind error that you're getting seems to suggest that your program terminated abnormally due to an exception. You can see this through the call stack: it looks like an internal std::__throw_exception function is getting called and that there's an object of type std::logic_error getting constructed. From context, it seems like what's happening here is that you passed an invalid argument into the std::string constructor, which then caused the std::logic_error to get thrown, causing a different std::string to get constructed and then thrown. Since the program terminated due to an exception, the destructors for the std::strings constructed this way never got called, hence the leak.
I'd run this program in gdb rather than valgrind to see if you can debug the source of the error. From what you've posted above I don't think we have enough context to provide any specific insights.
Problem here is when you passed string literal which is actually of type const char * (c string) to const string , compiler creates temporary object by invoking overaloded ctor string(const char * ). This temporary object is then passed by value to Foo().
Temporary object of type string has internal allocation created something on heap and it should be freed when temporary object goes out of scope.
This is not definite memory leak but valgrind thinks (due to temp object doesnot have definite starting pointer pointing to it) in that way.
That's the reason it is reported as possbily lost (and not definitely lost).
The idiom I like to use is Foo::Foo(const std::string &str)
Passes strings by reference, but also allows for string literals.
The one thing to look out for is a NULL char pointer. That is quite possibly what you are seeing.

I don't understand a valgrind error I'm getting

==3275== Invalid read of size 8
==3275== at 0x53D006E: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1362)
==3275== by 0x53C5C6C: fwrite (iofwrite.c:45)
==3275== by 0x4EE4C9D: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==3275== by 0x4EE4FA6: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==3275== by 0x401D4C: main (q2.cc:45)
==3275== Address 0x5a254b8 is 24 bytes inside a block of size 43 free'd
==3275== at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3275== by 0x4EF27BF: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==3275== by 0x40197D: read(std::istream&, character&) (utf8char.cc:16)
==3275== by 0x401B6C: main (q2.cc:27)
This is the relevant code:
infile = new ifstream(argv[1]);
character CurrChar;
character &UTF = CurrChar;
where character is a structure that holds 4 bytes. I don't think it's relevant.
q2.cc:27 utfchar = read(*infile, UTF)
q2.cc:44 catch (UTF8err err) {
q2.cc:45 cout << err.msg << ends;
q2.cc:46 ....
where err is :
struct UTF8err { // exception
const char *msg;`
UTF8err( const char *msg ) : msg( msg ) {}
};
utf8char.cc:16 string pad = " : invalid padding";
When you call c_str, the result is valid so long as the string isn't modified or destroyed. But when you throw, the stack is unwound, destroying the string. So the pointer points to something that no longer exists.
Perhaps change the type of msg from const char* to std::string. Perhaps make the string static. Perhaps make the UTF8err class manage its own memory.

error in valgrind while throwing exceptions

Hi everyone, im trying to complete a code involving my own exception but im having a few errors while running valgrind.
the errors dont happen all the time, usually only the first time tried. it seems as though the string of the exception is giving trouble but it still prints it when the exception is thrown...any ideas what might be causing the problems?
thx for your time :)
#include <iostream>
#include <sstream>
#include <exception>
using namespace std;
class wrongMessageIndex:public exception{
public:
int index;
public:
wrongMessageIndex(int& num){index=num;};
virtual const char* what() const throw(){
stringstream s;
string k="Wrong message index: ";
s<<k<<index;
return (s.str().c_str());
}
};
class NoUserInSystem:public exception{
public:
string user;
public:
NoUserInSystem(string name){user=name;};
virtual const char* what() const throw(){
string k=user;
k+=": no such user ";
return (k.c_str());
}
virtual ~NoUserInSystem() throw(){}
};
class MemoreyFail:public exception{
public:
virtual const char* what() const throw(){
return ("Unable to create new message or write in the right file");
}
virtual ~MemoreyFail() throw(){}
};
the part from which the exception is thrown
string user="";
int checker=0;
while(!file.eof()){
getline(file,user);
if(strcmp(user.c_str(),to_who.c_str())==0)
{
checker=-1;
}
}
if(checker!=-1||strcmp(this->nameOfUser.c_str(),to_who.c_str())==0){
throw NoUserInSystem(to_who);
}
this is where the exception is caught:
try{
this->sendSingleMessage();
}
catch(exception& e){
cout<<e.what()<<endl;
}
here a few of the errors i get
Welcome zamri , you have 2 new messages.
Eva would like to update you that:
What would you like to do?
(1) See the list of all messages
(2) Read the next new message
(3) Read a message by index number
(4) Read a complete correspondence
(5) Write a new message
(6) Write a new mass-message
(7) Quit
Please type you choice
5
To:tony
==2945== Invalid read of size 1
==2945== at 0x402C658: strlen (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2945== by 0x40CAC2D: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x804A144: main (in /home/ise/Ass4/myMs)
==2945== Address 0x4342834 is 12 bytes inside a block of size 32 free'd
==2945== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2945== by 0x40D699A: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x804D2A2: RegularUser::showMenue() (in /home/ise/Ass4/myMs)
==2945== by 0x804A144: main (in /home/ise/Ass4/myMs)
==2945==
==2945== Invalid read of size 1
==2945== at 0x402C663: strlen (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2945== by 0x40CAC2D: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x804A144: main (in /home/ise/Ass4/myMs)
==2945== Address 0x4342835 is 13 bytes inside a block of size 32 free'd
==2945== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2945== by 0x40D699A: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x804D2A2: RegularUser::showMenue() (in /home/ise/Ass4/myMs)
==2945== by 0x804A144: main (in /home/ise/Ass4/myMs)
==2945==
==2945== Invalid read of size 1
==2945== at 0x41B868B: _IO_file_xsputn##GLIBC_2.1 (fileops.c:1330)
==2945== by 0x41AD757: fwrite (iofwrite.c:45)
==2945== by 0x40C9075: __gnu_cxx::stdio_sync_filebuf<char, std::char_traits<char> >::xsputn(char const*, int) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x40CA9AA: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x40CAC3D: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x804A144: main (in /home/ise/Ass4/myMs)
==2945== Address 0x4342846 is 30 bytes inside a block of size 32 free'd
==2945== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2945== by 0x40D699A: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x804D2A2: RegularUser::showMenue() (in /home/ise/Ass4/myMs)
==2945== by 0x804A144: main (in /home/ise/Ass4/myMs)
==2945==
==2945== Invalid read of size 1
==2945== at 0x41B869F: _IO_file_xsputn##GLIBC_2.1 (fileops.c:1330)
==2945== by 0x41AD757: fwrite (iofwrite.c:45)
==2945== by 0x40C9075: __gnu_cxx::stdio_sync_filebuf<char, std::char_traits<char> >::xsputn(char const*, int) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x40CA9AA: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x40CAC3D: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x804A144: main (in /home/ise/Ass4/myMs)
==2945== Address 0x4342845 is 29 bytes inside a block of size 32 free'd
==2945== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2945== by 0x40D699A: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==2945== by 0x804D2A2: RegularUser::showMenue() (in /home/ise/Ass4/myMs)
==2945== by 0x804A144: main (in /home/ise/Ass4/myMs)
==2945==
return (s.str().c_str());
returns a pointer to the first element of the internal buffer of a temporary copy of the buffer of your stream object. So this pointer is dangling as soon as what() completes.
Basically the same problem:
return (k.c_str());
returns a pointer into the buffer of the local string k which will immediately go out of scope.
To solve this, just drop this pointer business and simply return an std::string by value.

how to free memory when using TinyXML?

I am looking over leak memory. I am working with Valgrind and i have some errors like:
Invalid read of size 1
==6643== at 0x4026CC4: strlen (mc_replace_strmem.c:282)
==6643== by 0x40D42DA: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
==6643== by 0x804B8AB: main
==6643== Address 0x441f895 is 13 bytes inside a block of size 45 free'd
==6643== at 0x4025504: operator delete(void*) (vg_replace_malloc.c:387)
==6643== by 0x40D1ACC: std::string::_Rep::_M_destroy(std::allocator<char> const&)
==6643== by 0x40D1B8B: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
==6643== by 0x804CE6A: TiXmlNode::~TiXmlNode()
==6643== by 0x80B6241: TiXmlText::~TiXmlText()
==6643== by 0x804D0B0: TiXmlNode::Clear()
==6643== by 0x804E13E: TiXmlElement::ClearThis()
The code is:
TiXmlHandle handle(&doc);
TiXmlElement* section,*pRoot,*pParam,*section1,*section2;
pRoot=doc.FirstChildElement("xml");
pParam=pRoot->FirstChildElement("Data");
while (pParam)
{
section = pParam->FirstChildElement("Name");
if (section)
{
const char* str= section->GetText();
long long int v;
sscanf(str, "%lld", &v);
}
Appreciate. THX