Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I encountered this problem while doing my assignments. When you have a class B that inherits class A, and B initializes variables in A by calling the constructor of A in B's constructor, the variable that is supposed to be initialized in A's constructor remains uninitialized. This doesn't seem to happen if we create an object of class A, even though seemingly the only difference is the inheritance and constructor chain.
Here is a minimal example:
#include <iostream>
#include <string>
class A {
public:
A(std::string s)
: s_(s) {}
~A(){}
void Print() const {
std::cout << s_ + "123";
}
private:
const std::string& s_;
};
class B : public A {
public:
B(std::string s)
: A(s) {}
};
int main()
{
//A a = A("123");
//a.Print();
B b = B("123");
b.Print();
}
In Print(), you can remove the extra string literal. This way the issue is focused on the variable not being initialized. But with the extra literal, according to valgrind, a million bytes are still reachable. This seems very weird.
Valgrind without literal in Print():
g++ -c -g -std=c++17 -Wall -Wextra -pedantic main.cpp -o main.o
g++ main.o -o main
valgrind ./main
==22551== Memcheck, a memory error detector
==22551== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22551== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==22551== Command: ./main
==22551==
==22551== error calling PR_SET_PTRACER, vgdb might block
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x4F4FA9A: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x545C928: fwrite (iofwrite.c:35)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x54689B4: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1226)
==22551== by 0x545C9E6: fwrite (iofwrite.c:39)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x5468A85: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1275)
==22551== by 0x545C9E6: fwrite (iofwrite.c:39)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x5468210: _IO_file_write##GLIBC_2.2.5 (fileops.c:1198)
==22551== by 0x5468B9E: new_do_write (fileops.c:457)
==22551== by 0x5468B9E: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1277)
==22551== by 0x545C9E6: fwrite (iofwrite.c:39)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Syscall param write(buf) contains uninitialised byte(s)
==22551== at 0x54ED264: write (write.c:27)
==22551== by 0x546822C: _IO_file_write##GLIBC_2.2.5 (fileops.c:1203)
==22551== by 0x5468B9E: new_do_write (fileops.c:457)
==22551== by 0x5468B9E: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1277)
==22551== by 0x545C9E6: fwrite (iofwrite.c:39)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Syscall param write(count) contains uninitialised byte(s)
==22551== at 0x54ED264: write (write.c:27)
==22551== by 0x546822C: _IO_file_write##GLIBC_2.2.5 (fileops.c:1203)
==22551== by 0x5468B9E: new_do_write (fileops.c:457)
==22551== by 0x5468B9E: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1277)
==22551== by 0x545C9E6: fwrite (iofwrite.c:39)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Syscall param write(buf) points to uninitialised byte(s)
==22551== at 0x54ED264: write (write.c:27)
==22551== by 0x546822C: _IO_file_write##GLIBC_2.2.5 (fileops.c:1203)
==22551== by 0x5468B9E: new_do_write (fileops.c:457)
==22551== by 0x5468B9E: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1277)
==22551== by 0x545C9E6: fwrite (iofwrite.c:39)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551== Address 0x1ffefff910 is on thread 1's stack
==22551== in frame #5, created by A::Print() const (main.cpp:14)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x5468BB0: new_do_write (fileops.c:458)
==22551== by 0x5468BB0: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1277)
==22551== by 0x545C9E6: fwrite (iofwrite.c:39)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x5468BEB: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1279)
==22551== by 0x545C9E6: fwrite (iofwrite.c:39)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x545CA65: fwrite (iofwrite.c:45)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x545CA6A: fwrite (iofwrite.c:45)
==22551== by 0x4F4FB83: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551== Conditional jump or move depends on uninitialised value(s)
==22551== at 0x4F4FB91: 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.25)
==22551== by 0x109BAF: A::Print() const (main.cpp:15)
==22551== by 0x1099EB: main (main.cpp:32)
==22551==
==22551==
==22551== HEAP SUMMARY:
==22551== in use at exit: 0 bytes in 0 blocks
==22551== total heap usage: 2 allocs, 2 frees, 73,216 bytes allocated
==22551==
==22551== All heap blocks were freed -- no leaks are possible
==22551==
==22551== For counts of detected and suppressed errors, rerun with: -v
==22551== Use --track-origins=yes to see where uninitialised values come from
==22551== ERROR SUMMARY: 13 errors from 13 contexts (suppressed: 0 from 0)
Valgrind with literal in Print():
(I had to cut the middle out to fit into the character limit, the whole thing is here: https://pastebin.com/UQmB0mXj)
g++ -c -g -std=c++17 -Wall -Wextra -pedantic main.cpp -o main.o
g++ main.o -o main
valgrind ./main
==22561== Memcheck, a memory error detector
==22561== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22561== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==22561== Command: ./main
==22561==
==22561== error calling PR_SET_PTRACER, vgdb might block
==22561== Conditional jump or move depends on uninitialised value(s)
==22561== at 0x10AC50: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:217)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561==
==22561== Conditional jump or move depends on uninitialised value(s)
==22561== at 0x10AD84: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned long&, unsigned long) (basic_string.tcc:137)
==22561== by 0x10AC69: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:219)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561==
...
had to cut here to fit into character limit
...
==22561==
==22561== Conditional jump or move depends on uninitialised value(s)
==22561== at 0x10A9F0: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long) (basic_string.h:337)
==22561== by 0x10AED7: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char*, char*) (basic_string.h:382)
==22561== by 0x10ACB0: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:225)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561==
==22561== Conditional jump or move depends on uninitialised value(s)
==22561== at 0x109DE1: std::char_traits<char>::copy(char*, char const*, unsigned long) (char_traits.h:348)
==22561== by 0x10AA1D: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long) (basic_string.h:340)
==22561== by 0x10AED7: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char*, char*) (basic_string.h:382)
==22561== by 0x10ACB0: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:225)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561==
==22561== Conditional jump or move depends on uninitialised value(s)
==22561== at 0x4C366E6: memmove (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22561== by 0x109E05: std::char_traits<char>::copy(char*, char const*, unsigned long) (char_traits.h:350)
==22561== by 0x10AA1D: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long) (basic_string.h:340)
==22561== by 0x10AED7: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char*, char*) (basic_string.h:382)
==22561== by 0x10ACB0: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:225)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561==
==22561== Conditional jump or move depends on uninitialised value(s)
==22561== at 0x4C36711: memmove (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22561== by 0x109E05: std::char_traits<char>::copy(char*, char const*, unsigned long) (char_traits.h:350)
==22561== by 0x10AA1D: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long) (basic_string.h:340)
==22561== by 0x10AED7: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char*, char*) (basic_string.h:382)
==22561== by 0x10ACB0: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:225)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561==
==22561== Conditional jump or move depends on uninitialised value(s)
==22561== at 0x4C367EE: memmove (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22561== by 0x109E05: std::char_traits<char>::copy(char*, char const*, unsigned long) (char_traits.h:350)
==22561== by 0x10AA1D: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long) (basic_string.h:340)
==22561== by 0x10AED7: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char*, char*) (basic_string.h:382)
==22561== by 0x10ACB0: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:225)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561==
==22561== Invalid read of size 8
==22561== at 0x4C367EE: memmove (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22561== by 0x109E05: std::char_traits<char>::copy(char*, char const*, unsigned long) (char_traits.h:350)
==22561== by 0x10AA1D: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long) (basic_string.h:340)
==22561== by 0x10AED7: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char*, char*) (basic_string.h:382)
==22561== by 0x10ACB0: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:225)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561== Address 0x1fff001000 is not stack'd, malloc'd or (recently) free'd
==22561==
==22561==
==22561== Process terminating with default action of signal 11 (SIGSEGV)
==22561== Access not within mapped region at address 0x1FFF001000
==22561== at 0x4C367EE: memmove (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22561== by 0x109E05: std::char_traits<char>::copy(char*, char const*, unsigned long) (char_traits.h:350)
==22561== by 0x10AA1D: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long) (basic_string.h:340)
==22561== by 0x10AED7: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char*, char*) (basic_string.h:382)
==22561== by 0x10ACB0: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:225)
==22561== by 0x10A7DD: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) (basic_string.h:236)
==22561== by 0x10A472: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) (basic_string.h:255)
==22561== by 0x10A15B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:440)
==22561== by 0x10A05E: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) (basic_string.h:5928)
==22561== by 0x109E66: A::Print() const (main.cpp:15)
==22561== by 0x109C8B: main (main.cpp:32)
==22561== If you believe this happened as a result of a stack
==22561== overflow in your program's main thread (unlikely but
==22561== possible), you can try to increase the size of the
==22561== main thread stack using the --main-stacksize= flag.
==22561== The main thread stack size used in this run was 8388608.
==22561==
==22561== HEAP SUMMARY:
==22561== in use at exit: 1,089,515 bytes in 1 blocks
==22561== total heap usage: 2 allocs, 1 frees, 1,162,219 bytes allocated
==22561==
==22561== LEAK SUMMARY:
==22561== definitely lost: 0 bytes in 0 blocks
==22561== indirectly lost: 0 bytes in 0 blocks
==22561== possibly lost: 0 bytes in 0 blocks
==22561== still reachable: 1,089,515 bytes in 1 blocks
==22561== suppressed: 0 bytes in 0 blocks
==22561== Rerun with --leak-check=full to see details of leaked memory
==22561==
==22561== For counts of detected and suppressed errors, rerun with: -v
==22561== Use --track-origins=yes to see where uninitialised values come from
==22561== ERROR SUMMARY: 197 errors from 12 contexts (suppressed: 0 from 0)
src.make:32: recipe for target 'valgrind-run' failed
make: *** [valgrind-run] Segmentation fault (core dumped)
My questions are:
Why does the compiler not give an error because of A's constructor? How can we set a reference with the value?
Why does this only give errors when there is inheritance involved?
Why does adding a literal in Print() have such a big effect? And why are a million bytes allocated because of this?
Why does the compiler not give an error because of A's constructor?
Presumably because A's constructor is well-formed, and thus the compiler must accept it in order to conform to the standard.
You are allowed to bind a reference to a local variable. The reference will be invalid after the constructor returns, but if the program never indirects through the reference after returning from the constructor, then that is technically no problem. It is not trivial for the compiler to prove that the program will do that (this problem is generally analogous to the halting problem).
A compiler does warn about it through:
warning: binding reference member 's_' to stack allocated parameter 's' [-Wdangling-field]
How can we set a reference with the value?
You have bound the reference to the local variable. It is unclear what you're trying to do, but probably you should not be using a reference member to achieve that.
Why ...
Why ...
Because behaviour of the program is undefined. Any change can affect the behaviour of the program in any way. The behaviour can even change without change to the program. Or it might not change. Nothing about the behaviour of the program is guaranteed.
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.