Stack buffer overflow error while submitting solution on leetcode - c++

I am trying to submit my solution on leetcode, when I submit it it gives me a run time error.
AddressSanitizer: stack-buffer-overflow on address 0x7ffd6484f411 at pc 0x000000386795 bp 0x7ffd6484ed70 sp 0x7ffd6484ed68
Here is my code:
int lengthOfLongestSubstring(std::string s)
{
auto start = std::begin(s);
std::string substring = std::string(std::begin(s), std::begin(s) + 1);
std::string pre_string = std::string(std::begin(s), std::begin(s) + 1);
for (auto itr = std::begin(s) + 1; itr != std::end(s); ++itr)
{
auto next = itr;
if (std::find(std::begin(substring), std::end(substring), *itr) ==
std::end(substring))
{
substring = std::string(start, itr + 1);
}
else
{
if (++next != std::end(s))
{
start = itr;
pre_string = substring;
substring = std::string(itr, ++itr);
}
}
}
if (pre_string.length() > substring.length())
{
return pre_string.length();
}
else
return substring.length();
}
when I try to run it on my machine, It does not give me any warning. It's running totally fine.
I am using the following command.
g++ -Wall -Wpedantic longestString.cpp -o long.o
and further I used valgrind to see the any problem but it also says there is no problem as you can see the output.
username#droozal:~/leetcode$ valgrind ./long.o
==9473== Memcheck, a memory error detector
==9473== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9473== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9473== Command: ./long.o
==9473==
5
==9473==
==9473== HEAP SUMMARY:
==9473== in use at exit: 0 bytes in 0 blocks
==9473== total heap usage: 2 allocs, 2 frees, 73,728 bytes allocated
==9473==
==9473== All heap blocks were freed -- no leaks are possible
==9473==
==9473== For counts of detected and suppressed errors, rerun with: -v
==9473== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
so my question is what can be the potential error? is something broken in my code Or what? Answers will be appreciated. Thanks.

I see that you're trying to solve with constant memory, I guess. You can use memoization though for this problem, much simpler to code/debug.
This'll pass through:
#include <string>
#include <map>
#include <algorithm>
class Solution {
public:
static inline int lengthOfLongestSubstring(const std::string s) {
map<char, int> char_map;
int start = -1;
int longest = 0;
const int length = s.size();
for (int index = 0; index < length; index++) {
if (char_map.count(s[index]) != 0) {
start = std::max(start, char_map[s[index]]);
}
char_map[s[index]] = index;
longest = std::max(longest, index - start);
}
return longest;
}
};
References
For additional details, you can see the Discussion Board. There are plenty of accepted solutions with a variety of languages and explanations, efficient algorithms, as well as asymptotic time/space complexity analysis1, 2 in there.

Related

C++ Valgrind FIX Conditional jump or move depends on uninitialised value(s)

I run my program using valgrind like this:
valgrind --leak-check=full ./a.out < in0.txt > out0.txt
and get the following output:
==13077== Memcheck, a memory error detector
==13077== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13077== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==13077== Command: ./a.out
==13077==
==13077== Conditional jump or move depends on uninitialised value(s)
==13077== at 0x40491F: OnGetMostViewedClasses (in /home/user/a.out)
==13077== by 0x404498: parser (in /home/user/a.out)
==13077== by 0x404263: main (in /home/user/a.out)
==13077==
==13077==
==13077== HEAP SUMMARY:
==13077== in use at exit: 0 bytes in 0 blocks
==13077== total heap usage: 90 allocs, 90 frees, 6,200 bytes allocated
==13077==
==13077== All heap blocks were freed -- no leaks are possible
==13077==
==13077== For counts of detected and suppressed errors, rerun with: -v
==13077== Use --track-origins=yes to see where uninitialised values come from
==13077== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
-bash-4.2$
while it refers to StatusType res; used in here:
static errorType OnGetMostViewedClasses(void* DS, const char* const command) {
int numOfClasses;
int *courses = NULL, *classes = NULL;
StatusType res;
ValidateRead(sscanf(command, "%d", &numOfClasses), 1, "%s failed.\n", commandStr[GETMOSTVIEWEDCLASSES_CMD]);
if (numOfClasses > 0) {
courses = (int *)malloc(numOfClasses * sizeof(int));
classes = (int *)malloc(numOfClasses * sizeof(int));
if (courses == NULL || classes == NULL) {
res = ALLOCATION_ERROR;
}
}
if (res != ALLOCATION_ERROR) {
res = GetMostViewedClasses(DS, numOfClasses, courses, classes);
}
if (res != SUCCESS) {
printf("%s: %s\n", commandStr[GETMOSTVIEWEDCLASSES_CMD], ReturnValToStr(res));
if (courses != NULL) free(courses);
if (classes != NULL) free(classes);
return error_free;
}
printf("%s: %s\n", commandStr[GETMOSTVIEWEDCLASSES_CMD], ReturnValToStr(res));
printf("Course\t|\tClass\n");
for (int i = 0; i < numOfClasses; i++)
{
printf("%d\t|\t%d\n", courses[i], classes[i]);
}
printf("--End of most viewed classes--\n");
if (courses != NULL) free(courses);
if (classes != NULL) free(classes);
return error_free;
}
and declared like this:
typedef enum {
SUCCESS = 0,
FAILURE = -1,
ALLOCATION_ERROR = -2,
INVALID_INPUT = -3
} StatusType;
So my question is, how can I solve this problem without changing the above code since it was given to us and my professor told: "you aren't allowed to change it" and "any errors found by valgrind will get you a mark of 0"?
Any ideas or suggestions are welcomed.
please note: except this problem I have 0 memory leak issue (According to 32 input files I tested)
Neither res nor numOfClasses is initialized. There are code paths that can result in these values being used in if statements without having a value assigned to them. scanf can fail, leaving numOfClasses uninitialized, and unless an error occurs in memory allocation res will not be assigned a value.
The solution is to initialize both:
int numOfClasses = 0;
StatusType res = SUCCESS;
As #1201ProgramAlarm points out, res is not initialized, and since it only gets set if numOfClasses is greater than zero and one of the malloc calls fails, you would need to somehow force the code into that code path. So, make sure the sscanf reads a value from command (command should be "1" or something like that), and then ... somehow cause malloc to return NULL. That's not trivial, but maybe you can add a clever line like #define malloc(x) NULL somewhere above that function? This entire exercise seems pretty terrible, TBH.
Edit: Alternatively, make malloc fail by asking for TOO MUCH memory. If numOfClasses is something like SIZE_MAX/sizeof(int), there's a pretty good chance you won't be able to allocate two blocks of memory that big, and one or both malloc calls will return NULL. That sets the res variable, and there won't be an uninitialized read. Stupid, stupid, stupid.
This is tagged C++, but the code, with typedef enum, void*, malloc, printf and scanf smells badly of C. That is not a good way to learn C++.
You don't provide a definition of ValidateRead. You might just be able to subvert the preprocessor to do what you need, but this will be tortuous.
What the code really should do is res = ValidateRead(... where ValidateRead is a function that returns SUCCESS or INVALID_INPUT.

Do I need to deallocate object pointers in a vector?

I'm confused as to how deallocating vector memory works.
For the example below,
vector<Object*> vec;
for(int i = 0; i < 10; i++){
Object* obj = new Object();
vec.push_pack(obj);
}
//DEALLOCATE CODE HERE//
What should I do to deallocate vec properly?
The program seems to run fine as it is but I'm not sure.
avoid using new/delete :
std::vector<std::unique_ptr<Object>> vec;
for(int i = 0; i < 10; i++)
{
vec.push_pack(std::make_unique<Object>());
}
the unique_ptr will take care of deletion
how deallocating
for instance do
for(auto o : vect){
delete o;
}
vect.clear();
Note you written push_pack rather than push_back to fill the vector
making a full program :
#include <vector>
using namespace std;
class Object{};
int main()
{
vector<Object*> vec;
for(int i = 0; i < 10; i++){
Object* obj = new Object();
vec.push_back(obj);
}
for(auto o : vec){
delete o;
}
vec.clear();
}
Compilation and execution under valgrind :
pi#raspberrypi:/tmp $ g++ v.cc
pi#raspberrypi:/tmp $ valgrind ./a.out
==9157== Memcheck, a memory error detector
==9157== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9157== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9157== Command: ./a.out
==9157==
==9157==
==9157== HEAP SUMMARY:
==9157== in use at exit: 0 bytes in 0 blocks
==9157== total heap usage: 16 allocs, 16 frees, 20,358 bytes allocated
==9157==
==9157== All heap blocks were freed -- no leaks are possible
==9157==
==9157== For counts of detected and suppressed errors, rerun with: -v
==9157== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
all allocated memory was freed

How to correctly use and free asn1c SEQUENCE_OF?

I'm using the asn1c lib for many projects, but I never found how to use the free member of a SEQUENCE_OF. I always set it to nullptr because of that, and when I use Valgrind, I see (of course) that my lists members are not freed when using ASN_STRUCT_FREE on the element containing the list.
So my question is how can I use that free member?
Here is a simple example of how I use my lists with asn1c.
ListItem_t *li = nullptr;
StructWList_t swl;
swl.list.count = 0;
swl.list.size = 0;
swl.list.free = nullptr; // How can I feed it properly?
swl.list.array = reinterpret_cast<ListItem_t**>(calloc(1, sizeof *swl.list.array));
for(int i = 0 ; i < 5 ; i++)
{
li = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *li));
*li = i;
// Valgrind says that the calloc below is definitly lost
swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
ASN_SEQUENCE_ADD(&swl, li);
}
...
ASN_STRUCT_FREE(ASN_DEF_StructWList, &swl);
Does anyone know how to feed it properly?
EDIT
My version of asn1c is the v0.9.29 from git repository in AUR (on Archlinux).
The above ASN.1 is as follow:
Example
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
StructWList ::= SEQUENCE OF ListItem
ListItem ::= INTEGER
END
Thanks in advance,
Emilien
// Valgrind says that the calloc below is definitly lost
swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
ASN_SEQUENCE_ADD(&swl, li);
The ASN_SEQUENCE_ADD will overwrite the pointer you stored on the previous line. You should either store it manually as on the first line or call ASN_SEQUENCE_ADD but not both.
Also you should fully initialize swl as it contains more members (_asn_ctx) and use ASN_STRUCT_FREE_CONTENTS_ONLY as swl is allocated on the stack and cannot be freed.
--- main.cpp.orig 2019-05-07 20:49:25.880336931 +0300
+++ main.cpp 2019-05-07 20:59:10.192431926 +0300
## -3,7 +3,7 ##
int main()
{
ListItem_t *li = nullptr;
- StructWList_t swl;
+ StructWList_t swl = {0};
swl.list.count = 0;
swl.list.size = 0;
## -15,8 +15,8 ##
li = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *li));
*li = i;
// Valgrind says that the calloc below is definitly lost
- swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
+ //swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
ASN_SEQUENCE_ADD(&swl, li);
}
- ASN_STRUCT_FREE(ASN_DEF_StructWList, &swl);
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_StructWList, &swl);
}
Compile with g++ -Wall -I. -ggdb -O0 -o test main.cpp libasncodec.a
valgrind --tool=memcheck ./test
==29555== Memcheck, a memory error detector
==29555== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==29555== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==29555== Command: ./test
==29555==
==29555==
==29555== HEAP SUMMARY:
==29555== in use at exit: 0 bytes in 0 blocks
==29555== total heap usage: 9 allocs, 9 frees, 72,848 bytes allocated
==29555==
==29555== All heap blocks were freed -- no leaks are possible
==29555==
==29555== For counts of detected and suppressed errors, rerun with: -v
==29555== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Memory leak with template for pointers and ints. What am i doing wrong?

Getting to know C++, and trying to template a class to work with Ints and Pointers for a struct.
The output is as expected, but testing with valgrind there seems to be a memory leek, from an unfreed memory.
I believe it has something to do with the way i declare the list variable in the class init.
What am I missing and how can i fix it?
Thanks.
#include <stdio.h>
template <class T>
class List {
T* list;
public:
int length;
List(int len) {
list = new T[len];
length = len;
}
virtual ~List() {
delete[] list;
}
T get(int index) {
return list[index];
}
void set(int index, T val) {
list[index] = val;
}
};
/*
You shouldn't change the code below, unless you want to _temporarily_ change the main function while testing.
Change it back when you're done.
*/
typedef struct Point_ {
int x;
int y;
} Point;
int main(){
List<int> integers(10);
for(int i = 0; i < integers.length; i++){
integers.set(i, i * 100);
printf("%d ", integers.get(i));
}
printf("\n"); // this loop should print: 0 100 200 300 400 500 600 700 800 900
List<Point *> points(5);
for(int i = 0; i < points.length; i++) {
Point *p = new Point;
p->x = i * 10;
p->y = i * 100;
points.set(i, p);
printf("(%d, %d) ", points.get(i)->x, points.get(i)->y);
delete p;
}
printf("\n"); // this loop should print: (0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
}
compiled with g++ like this:
g++ -Wall p2_templates.cpp -o p2_templates
Used valgrind with this command:
valgrind --tool=memcheck ./p2_templates
Getting this result from valgrind:
==22396== Memcheck, a memory error detector
==22396== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==22396== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==22396== Command: ./p2_templates
==22396==
0 100 200 300 400 500 600 700 800 900
(0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
==22396==
==22396== HEAP SUMMARY:
==22396== in use at exit: 72,704 bytes in 1 blocks
==22396== total heap usage: 9 allocs, 8 frees, 73,848 bytes allocated
==22396==
==22396== LEAK SUMMARY:
==22396== definitely lost: 0 bytes in 0 blocks
==22396== indirectly lost: 0 bytes in 0 blocks
==22396== possibly lost: 0 bytes in 0 blocks
==22396== still reachable: 72,704 bytes in 1 blocks
==22396== suppressed: 0 bytes in 0 blocks
==22396== Rerun with --leak-check=full to see details of leaked memory
==22396==
==22396== For counts of detected and suppressed errors, rerun with: -v
==22396== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
First of all read the valgrind output VERY CAREFULLY and ENTIRELY (and do everything what valgrind recommends). In your case the fragments of interest are:
Rerun with --leak-check=full to see details of leaked memory
still reachable: 72,704 bytes in 1 blocks
You should also be aware of the following:
http://valgrind.org/docs/manual/faq.html#faq.reports (4.1. My program uses the C++ STL and string classes. Valgrind reports 'still reachable' memory leaks involving these classes at the exit of the program, but there should be none).
And if you have time you may strongly benefit from detailed understanding of this: http://valgrind.org/docs/manual/mc-manual.html#mc-manual.leaks (4.2.8. Memory leak detection).
Finally you can find tons of useful info here: http://valgrind.org (valgrind homepage).
A strong grasp of basic data structures is good! I encourage you to explore it fully. Once you have grip on the basics then the STL can be very useful to take care of the busy work while you think about the hard problems.
There are no leaks in your code. Valgrind is seeing the memory elsewhere, as noted you can use the --leak-check=full to get more details. Its good that you are trying to understand those details.
This is a dangling pointer problem however.
#include <stdio.h>
template <class T>
class List {
T* list;
public:
int length;
List(int len) {
list = new T[len];
length = len;
}
virtual ~List() {
delete[] list;
}
T get(int index) {
return list[index];
}
void set(int index, T val) {
list[index] = val;
}
};
/*
You shouldn't change the code below, unless you want to _temporarily_ change the main function while testing.
Change it back when you're done.
*/
typedef struct Point_ {
int x;
int y;
} Point;
int main(){
List<int> integers(10);
for(int i = 0; i < integers.length; i++){
integers.set(i, i * 100);
printf("%d ", integers.get(i));
}
printf("\n"); // this loop should print: 0 100 200 300 400 500 600 700 800 900
List<Point *> points(5);
for(int i = 0; i < points.length; i++) {
Point *p = new Point;
p->x = i * 10;
p->y = i * 100;
points.set(i, p);
printf("(%d, %d) ", points.get(i)->x, points.get(i)->y);
delete p;
}
Point* fail = points.get(0);
fail->x = 0;
fail->y = 0;
printf("\n"); // this loop should print: (0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
}
Note that I added the 'fail' variable after the points loop to demonstrate the issue. The points variable is declared and populated fine but then the contents are deleted. The List holds Point* rather than Point, as such when the delete occurs the pointer in the List is 'dangling'. Dangling pointer use will crash or corrupt the heap almost every time. This is a common problem with the STL containers as well when holding pointers.
A big flaw in C++ is the heap management. Correctly using the heap is very difficult with the biggest problem being ownership hand off. Dangling pointers or leaks often result from confusion on who owns the pointer. There is a brief article here Avoiding Leaks in C++
Running this program under Valgrind will show Invalid write errors. Give it a try.

Issue on RHEL4 release using boost 1.36 and C++

I am struggling with a mysterious problem
I only see on my RHEL4 release build. Some of my unit tests (using boost 1.36 unit test framework) fail on RHEL4 (gcc 3.4.6) and using release build-type. I do not see the problem using RHEL5 release or debug build types (gcc 4.1.2, boost-1.39); neither do I
see it on Windows 32 bit or 64 bit using either Visual Studio 2005 (using boost-1.36) or 2008 (using boost-1.39).
Suspecting that this may be due to some subtle memory issue, I proceeded to run valgrind on the test application (minimal case that preserved the problem). Here is what I got when I ran valgrind using "full, no-reachable" mode:
==12285== Memcheck, a memory error detector.
==12285== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==12285== Using LibVEX rev 1575, a library for dynamic binary translation.
==12285== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==12285== Using valgrind-3.1.1, a dynamic binary instrumentation framework.
==12285== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==12285== For more details, rerun with: -v
==12285==
==12285== My PID = 12285, parent PID = 12284. Prog and args are:
==12285== ./myprojd
==12285==
==12285== Syscall param sigaltstack(ss) points to uninitialised byte(s)
==12285== at 0x3AD682EDA9: sigaltstack (in /lib64/tls/libc-2.3.4.so)
==12285== by 0x6488638: boost::detail::signal_handler::~signal_handler()
(in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0)
==12285== by 0x648975E: boost::execution_monitor::catch_signals
(boost::unit_test::callback0<int> const&)
(in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0)
==12285== by 0x6489813: boost::execution_monitor::execute
(boost::unit_test::callback0<int> const&)
(in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0)
==12285== by 0x648F2E4: boost::unit_test::framework::run(unsigned long, bool)
(in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0)
==12285== by 0x649BD02: boost::unit_test::unit_test_main(bool (*)(), int, char**)
(in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0)
==12285== by 0x4147F0: main (init.cpp:132)
==12285== Address 0x7FEFFF3B0 is on thread 1's stack
==12285==
==12285== ERROR SUMMARY: 6 errors from 1 contexts (suppressed: 4 from 1)
==12285== malloc/free: in use at exit: 190,112 bytes in 1,869 blocks.
==12285== malloc/free: 23,128 allocs, 21,259 frees, 2,520,845 bytes allocated.
==12285== For counts of detected errors, rerun with: -v
==12285== searching for pointers to 1,869 not-freed blocks.
==12285== checked 2,184,272 bytes.
==12285==
==12285== LEAK SUMMARY:
==12285== definitely lost: 0 bytes in 0 blocks.
==12285== possibly lost: 0 bytes in 0 blocks.
==12285== still reachable: 190,112 bytes in 1,869 blocks.
==12285== suppressed: 0 bytes in 0 blocks.
==12285== Reachable blocks (those to which a pointer was found) are not shown.
==12285== To see them, rerun with: --show-reachable=yes
Ofcourse, I ran this in debug mode (although as I mentioned the error occurs only in release mode). If I run valgrind in release mode, I get the same output (with perhaps
less detail such as line #s). From this it appears that the problem is somehow in boost-1.36, or perhaps my definition of init_unit_test_suite? Clearly one thing I can try is
to run using boost-1.39 on all platforms; but unfortunately, we're currently on boost-1.36 for RHEL4 and VS2005, and so this may not be practical yet.
I also observe that forcing a certain logger output to console at a point where the test fails, enables the test to pass (not good, I know)! Suspecting that this might be due that I commented all logger output and ran valgrind - so that's what's posted above. If you need some code snippets of the init_unit_test_suite function; I can post that, if it helps. Any ideas to resolve this are welcome and greatly appreciated.
05/26/2011 Edit:
Here's the init_unit_test_suite - appreciate if somebody could take a look.
std::ofstream log_stream;
std::ofstream report_stream;
const_string retrieve_framework_parameter( const_string cla_name, int argc, char** argv ) {
//- first try to find parameter among command line arguments if present
if( argc ) {
//- locate corresponding cla name
if( !cla_name.is_empty() ) {
for( int i = 1; i < argc; ++i ) {
if( cla_name == const_string( argv[i], cla_name.size() ) && argv[i][cla_name.size()] == '=' ) {
const_string result = argv[i] + cla_name.size() + 1;
for( int j = i; j < argc; ++j ) {
argv[j] = argv[j+1];
}
--argc;
return result;
}
}
}
}
return std::getenv( cla_name.begin() );
}
//! Format results to CPP UNIT xml
class simple_report_formatter : public results_reporter::format {
public:
virtual void results_report_start( std::ostream&) {
}
virtual void results_report_finish( std::ostream&) {
}
virtual void test_unit_report_start(test_unit const&, std::ostream&) {
}
virtual void test_unit_report_finish(test_unit const& tu, std::ostream& out) {
if( tu.p_type == tut_case ) {
const test_results& r = results_collector.results(tu.p_id);
if( r.passed() ) {
out<<"[PASS] ";
} else {
out<<"[FAIL] ";
}
out<<"Test Case <unit_"<<tu.p_name.get()<<"> ";
if( !r.passed() ) {
out<<" - ";
out<<"!! Assertions failed: "<<r.p_assertions_failed;
out<<" - See log files for details on failures !!";
}
out<<std::endl;
#if defined(MYPROJ_WINDOWS) && defined(MYPROJ_DEBUG)
if( !r.passed() ) {
std::ostringstream msg;
msg<<"!! "<<tu.p_name.get()<<" FAILED !!"<<std::endl;
OutputDebugStringA(msg.str().c_str());
}
#endif
}
}
virtual void do_confirmation_report(test_unit const&, std::ostream&) {
}
};
bool init_unit_test_suite() {
const_string log_file = retrieve_framework_parameter(
"--log_file",
framework::master_test_suite().argc,
framework::master_test_suite().argv
);
if( !log_file.empty() ) {
log_stream.open(log_file.begin());
unit_test_log.set_stream(log_stream);
}
const_string report_file = retrieve_framework_parameter(
"--report_file",
framework::master_test_suite().argc,
framework::master_test_suite().argv
);
if( !report_file.empty() ) {
report_stream.open(report_file.begin());
results_reporter::set_stream(report_stream);
}
if( runtime_config::report_format() == CLF ) {
results_reporter::set_format(new simple_report_formatter);
}
// This is providing the sensible default configuration when the test is being run
// without any input parameters whatsoever: print the final report to console
if( framework::master_test_suite().argc <= 1 ) {
results_reporter::set_stream(std::cout);
results_reporter::set_format(new simple_report_formatter);
results_reporter::set_level(DETAILED_REPORT);
}
framework::master_test_suite().p_name.set(MYPROJ_TEST_SUITE_NAME);
return true;
}
This "error" in valgrind is not necessarily a problem. When a system call is called in Linux the memory often has to be copied from users space to kernel space. In doing so the it may copy uninitialized bytes.
Just because it copies these bytes into kernel space does not mean the kernel will actually do anything with the uninitialized bytes. What the kernel does with the bytes depends heavily on the semantics of the system call in question.
Valgrind has no simple way of knowing if it is OK that some of the bytes passed in the system call are uninitialized so it always signals an error. Many of similar errors are suppressed by valgrind.
You can see some of valgrind's default suppressions in this file: /usr/lib/valgrind/default.supp You can also create your own suppression files if you like and use them in your unit test to suppress the error message. If you are not experiencing any actual problems on this system them suppressing the error is probably a good idea. See valgrind's command line options.