I am using "std::stringstream", for converting "long" value to "hex-string", for further usage in code.
Code snippet as below:
void initDisplayVariant(){
...
/// integer value to hex-string
std::stringstream sstream;
sstream << "0x"
<< std::setfill ('0') << std::setw(2)
<< std::hex << (int)frntDispVariant;
std::string frntDispVariantHex = sstream.str();
sstream.clear(); //clears out the stream-string
...
}
But, valgrind lists the location in "reachable-leaks".
...
==6736== 0 bytes in 1 blocks are still reachable in loss record 1 of 143
==6736== at 0x4024045: operator new[](unsigned int) (vg_replace_malloc.c:299)
==6736== by 0x5232570: std::__numpunct_cache<char>::_M_cache(std::locale const&) (in /usr/lib/libstdc++.so.6.0.14)
==6736== by 0x5236684: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.14)
==6736== by 0x523678D: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.14)
==6736== by 0x5241B43: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.14)
==6736== by 0x5241CB4: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.6.0.14)
==6736== by 0x808E76B: initDisplayVariant() (src.cpp:45)
...
Since the stream is local to method and should not exist beyond the method's scope (even though it does alloc internally), so the context of reported-leak is not clear.
Any clue or suggestion?
Related
I have this code:
#include <iostream>
using namespace std;
int main()
{
int tmp = 5;
int * arr = new int[tmp];
for(int i = 0; i < 7; i++)
{
if (i == tmp) //if count of values is equal to max size of arr then create new arr with more space
{
int * s = new int[tmp]; // reserve memory
for(int i = 0; i < (tmp); i++)
{
s[i] = arr[i]; //fill reserve memory with values from array arr
}
delete [] arr; // delete arr array
tmp *= 2; //twice more space for array
arr = new int[tmp]; //create new arr with twice more space
for (int i = 0; i < (tmp / 2); i++)
{
arr[i] = s[i]; // add values from old short arr to new arr with more space
}
delete [] s; // delete reserve memory
}
arr[i] = 1; //add 1 to position i in array
}
//show array
for (int j = 0; j < tmp; j++)
cout << arr[j] << " ";
cout << endl;
delete [] arr; //delete arr
return 0;
}
And I do not understand this error from valgrind:
==2664==
==2664== Conditional jump or move depends on uninitialised value(s)
==2664== at 0x4EBFCDE: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4EC02BC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4ECC06D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x400AE1: main (in /home/vojta/Dokumenty/C++/vstup do pole/a.out)
==2664== Uninitialised value was created by a heap allocation
==2664== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2664== by 0x400A2D: main (in /home/vojta/Dokumenty/C++/vstup do pole/a.out)
==2664==
==2664== Use of uninitialised value of size 8
==2664== at 0x4EBFBC3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4EBFD05: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4EC02BC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4ECC06D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x400AE1: main (in /home/vojta/Dokumenty/C++/vstup do pole/a.out)
==2664== Uninitialised value was created by a heap allocation
==2664== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2664== by 0x400A2D: main (in /home/vojta/Dokumenty/C++/vstup do pole/a.out)
==2664==
==2664== Conditional jump or move depends on uninitialised value(s)
==2664== at 0x4EBFBCF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4EBFD05: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4EC02BC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4ECC06D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x400AE1: main (in /home/vojta/Dokumenty/C++/vstup do pole/a.out)
==2664== Uninitialised value was created by a heap allocation
==2664== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2664== by 0x400A2D: main (in /home/vojta/Dokumenty/C++/vstup do pole/a.out)
==2664==
==2664== Conditional jump or move depends on uninitialised value(s)
==2664== at 0x4EBFD33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4EC02BC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x4ECC06D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==2664== by 0x400AE1: main (in /home/vojta/Dokumenty/C++/vstup do pole/a.out)
==2664== Uninitialised value was created by a heap allocation
==2664== at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2664== by 0x400A2D: main (in /home/vojta/Dokumenty/C++/vstup do pole/a.out)
==2664==
1 1 1 1 1 1 1 0 0 0
==2664==
==2664== HEAP SUMMARY:
==2664== in use at exit: 0 bytes in 0 blocks
==2664== total heap usage: 3 allocs, 3 frees, 80 bytes allocated
==2664==
==2664== All heap blocks were freed -- no leaks are possible
==2664==
==2664== For counts of detected and suppressed errors, rerun with: -v
==2664== ERROR SUMMARY: 12 errors from 4 contexts (suppressed: 0 from 0)
I find out that if I run this cycle
for(int i = 0; i < 7; i++)
{
to 10 not only to 7, valgrind do not show any errors.
I want to ask you, if my idea of having some positions in array empty, is wrong? I do not know if my code is correct for creating array depending on how much values you want to add. Does it exist some other ways, how to create larger array if you need it?
I tried to run valgrind with --track-origins=yes but couldn't find answer in it.
I'm new to C++, so I'm happy for every new ideas or hints.
Thank you for your time.
Once this array grows to five int, the shown code grows it to ten elements, and proceeds to add two additional ints, #5 and #6, to the array (I am using 0-based indexes to refer to the individual ints in the array).
The for loop at the end will attempt to print all 10 values of the array. Including the uninitialized values, #7 through #9. That's what valgrind is telling you.
valgrind's diagnostic is nearly undecipherable because uninitialized memory usage doesn't actually occur until you're deep in the bowels of the I/O library. The bug is in the main() function, but all it does is pass a reference to an uninitialized value to the I/O library. That doesn't trigger undefined behavior until the uninitialized value is actually grabbed inside the I/O library, for formatting.
P.S.: the array is grown first by copying the contents of the array to a new s array. The original arr gets deleted and replaced by the new 10 element arr, then the five values get copied back from s and s gets deleted.
This is a lot of unnecessary copying. It's sufficient to allocate the new 10 element array, copy the existing contents to it, then delete the original, and replace it with the new array.
Your question has been answered already, but next time, know that if you compile your code with the -g3 flag in g++, valgrind will also show you line numbers that the problems occurred. For example, compile with g++ teste.cpp -g3 and valgrind --track-origins=yes ./a.out will give you:
==20609== Memcheck, a memory error detector
==20609== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==20609== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==20609== Command: ./a.out
==20609==
==20609== Conditional jump or move depends on uninitialised value(s)
==20609== at 0x4F3CCAE: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F3CEDC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F493F9: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x400AE0: main (teste.cpp:31)
==20609== Uninitialised value was created by a heap allocation
==20609== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20609== by 0x400A2B: main (teste.cpp:20)
==20609==
==20609== Use of uninitialised value of size 8
==20609== at 0x4F3BB13: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F3CCD9: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F3CEDC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F493F9: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x400AE0: main (teste.cpp:31)
==20609== Uninitialised value was created by a heap allocation
==20609== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20609== by 0x400A2B: main (teste.cpp:20)
==20609==
==20609== Conditional jump or move depends on uninitialised value(s)
==20609== at 0x4F3BB1F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F3CCD9: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F3CEDC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F493F9: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x400AE0: main (teste.cpp:31)
==20609== Uninitialised value was created by a heap allocation
==20609== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20609== by 0x400A2B: main (teste.cpp:20)
==20609==
==20609== Conditional jump or move depends on uninitialised value(s)
==20609== at 0x4F3CD0C: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F3CEDC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x4F493F9: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==20609== by 0x400AE0: main (teste.cpp:31)
==20609== Uninitialised value was created by a heap allocation
==20609== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20609== by 0x400A2B: main (teste.cpp:20)
==20609==
1 1 1 1 1 1 1 0 0 0
==20609==
==20609== HEAP SUMMARY:
==20609== in use at exit: 72,704 bytes in 1 blocks
==20609== total heap usage: 5 allocs, 4 frees, 73,808 bytes allocated
==20609==
==20609== LEAK SUMMARY:
==20609== definitely lost: 0 bytes in 0 blocks
==20609== indirectly lost: 0 bytes in 0 blocks
==20609== possibly lost: 0 bytes in 0 blocks
==20609== still reachable: 72,704 bytes in 1 blocks
==20609== suppressed: 0 bytes in 0 blocks
==20609== Rerun with --leak-check=full to see details of leaked memory
==20609==
==20609== For counts of detected and suppressed errors, rerun with: -v
==20609== ERROR SUMMARY: 12 errors from 4 contexts (suppressed: 0 from 0)
This tells you that the uninitialised values where used in line 31, and they were created by the new in line 20.
This might be very helpfull.
I am trying to control de workflow of a program I am developing. To do so I have a map< unsigned int, list < unsigned int > > in which the first key will be the id and the second ( the list ) will be used to know if I end correctly all tasks. The only operations I use on this list are:
myMap[iD].size()
myMap[iD].push_back(foo) <- ( foo is an unsigned int )
for (std::list<unsigned int>::iterator it=myMap[iD].begin(); it != myMap[iD].end(); ++it){
myMap[iD].erase(it)
}
The length of my map can grow to 1452 elements and each element list size can be from the order of 1000 ~ 5000.
When I run the program sometimes I receive a segmentation fault and some times a bad allocation error. My guess is that this come from the push_back because:
If I don't push back any element the program works fine.
The storage for the new elements is allocated using the container's allocator, which may throw exceptions on failure (for the default allocator, bad_alloc is thrown if the allocation request does not succeed). http://www.cplusplus.com/reference/list/list/push_back/
This is the only part of the code where I use the map:
if (FOO != 0){
if (PID != 0){
if ( myMap.size() + 5 < myMap.max_size()){
if (myMap[PID].size() > 1000) myMap[PID].pop_front();
myMap[PID].push_back(EVENTVALUE);
}
}
} else {
if (PID != 0 and foo2 != 0 and myMap.find(PID) != myMap.end()) {
for (std::list<unsigned int>::iterator it=myMap[PID].begin(); it != myMap[PID].end(); ++it){
if (*it == foo2){
cout << " erasing pid: " << PID << endl;
myMap[PID].erase(it);
if ( myMap[PID].size() == 0 ) myMap.erase(PID);
break;
}
}
}
}
I've also tried to use the tool Valgrind and this is the output:
==4092== Invalid read of size 8
==4092== at 0x4F09EB8: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21)
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120)
==4092== by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254)
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393)
==4092== by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905)
==4092== by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1743)
==4092== by 0x404F49: main (foo.cc:3159)
==4092== Address 0x6157d08 is 0 bytes after a block of size 8 alloc'd
==4092== at 0x4C29670: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==4092== by 0x40DB77: allocate (new_allocator.h:104)
==4092== by 0x40DB77: _M_allocate (stl_vector.h:168)
==4092== by 0x40DB77: void std::vector<std::string, std::allocator<std::string> >::_M_emplace_back_aux<std::string>(std::string&&) (vector.tcc:404)
==4092== by 0x408F3E: push_back (stl_vector.h:920)
==4092== by 0x408F3E: split(std::string const&, char, int) (foo.cc:416)
==4092== by 0x41577F: lustreLine::toPRV(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1741)
==4092== by 0x404F49: main (foo.cc:3159)
==4092==
==4092== Invalid read of size 4
==4092== at 0x4F09EBB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21)
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120)
==4092== by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254)
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393)
==4092== by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905)
==4092== by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1743)
==4092== by 0x404F49: main (foo.cc:3159)
==4092== Address 0xfffffffffffffff8 is not stack'd, malloc'd or (recently) free'd
==4092==
==4092==
==4092== Process terminating with default action of signal 11 (SIGSEGV)
==4092== Access not within mapped region at address 0xFFFFFFFFFFFFFFF8
==4092== at 0x4F09EBB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21)
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120)
==4092== by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254)
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393)
==4092== by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905)
==4092== by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (fpp.cc:1743)
==4092== by 0x404F49: main (foo.cc:3159)
==4092== If you believe this happened as a result of a stack
==4092== overflow in your program's main thread (unlikely but
==4092== possible), you can try to increase the size of the
==4092== main thread stack using the --main-stacksize= flag.
==4092== The main thread stack size used in this run was 8388608.
[...]
( If more output is need just ask )
I've had to change some variable names for privacy, hope this is not a problem.
Thanks for reading and have a nice day!
The first for loop is wrong:
for (std::list<unsigned int>::iterator it=myMap[iD].begin(); it != myMap[iD].end(); ++it){
myMap[iD].erase(it);
}
because the iterator it becomes invalid after each call to erase.
You could re-write it as:
for (auto it = myMap[iD].begin(); it != myMap[iD].end(); )
{
it = myMap[iD].erase(it);
}
or better yet just
myMap[iD].clear();
There seem to be other for loops in your question where you make a similar mistake - in general you need to use the pattern:
for (auto it = foo.begin(); it != foo.end(); )
{
if (some_condition)
it = foo.erase(it); // erase map entry, update iterator
else
++it; // bump iterator
}
See the example on the cppreference.com entry for std::map::erase.
==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.
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.
I have the following error when using valgrind:
==3099== Conditional jump or move depends on uninitialised value(s)
==3099== at 0x40BA65D: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x40BA98C: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x40C5A98: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x40C5C13: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x80A5CC6: Ser::method() (in /home/user)
==3099== by 0x80BCA61: bool Ser() (in /home/user)
==3099== by 0x80958D1: Ser::Select() (in /home/user)
==3099== by 0x804B85D: main (in /home/user)
==3099==
==3099== Use of uninitialised value of size 4
==3099== at 0x40BA12E: ??? (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x40BA693: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x40BA98C: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x40C5A98: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x40C5C13: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.6.0.14)
==3099== by 0x80A5CC6: Ser::method() (in /home/user)
==3099== by 0x80BCA61: bool Ser::Call() (in /home//user)
==3099== by 0x80958D1: Ser::Select() (in /home/user)
==3099== by 0x804B85D: main (in /home/user)
What does this mean?
Where is the error?
This error means that you are working with some variables before they were initialized. Looks like you are printing uninitialized int value in Ser::method(). You should initialize it before printing.