Reputation: 21
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==
Upvotes: 1
Views: 593
Reputation: 50063
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.
Upvotes: 2