Question

My test.cpp contains following code. I profiled it with valgrind and valgrind shows errors. What am I missing ?

#include<string>
#include<cstring>
#include<iostream>

void TestString(std::string & str)
{
    char * tmpBuff = new char[3];
    tmpBuff[0] = 'f';
    tmpBuff[1] = 'o';
    tmpBuff[2] = 'o';
    str = tmpBuff;
    delete [] tmpBuff;
}

int main(int argc, char* argv[])
{
    std::string test_string;
    TestString(test_string);
    std::cout<<test_string;
    return 0;
}

valgrind-log

==5026== Invalid read of size 1
==5026==    at 0x4A07F64: strlen (mc_replace_strmem.c:403)
==5026==    by 0x347E29E14B: std::string::operator=(char const*) (in /usr/lib64/libstdc++.so.6.0.13)
==5026==    by 0x4009AD: TestString(std::string&) (test.cpp:11)
==5026==    by 0x4009EC: main (test.cpp:18)
==5026==  Address 0x4c22043 is 0 bytes after a block of size 3 alloc'd
==5026==    at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==5026==    by 0x400979: TestString(std::string&) (test.cpp:7)
==5026==    by 0x4009EC: main (test.cpp:18)
Was it helpful?

Solution 2

Try the following fix

void TestString(std::string & str)
{
    char * tmpBuff = new char[4]; // <<<
    tmpBuff[0] = 'f';
    tmpBuff[1] = 'o';
    tmpBuff[2] = 'o';
    tmpBuff[3] = '\0'; // <<<
    str = tmpBuff;
    delete [] tmpBuff;
}

C-style strings need a terminating \0 character.

OTHER TIPS

tmpBuff is missing the terminating \0.

It should contain the 4 chars: 'f', 'o', 'o', '\0'.

The std::string(const char*) constructor you are calling expects a nul terminated string. You are not passing it one, so the result is undefined behaviour. The constructor will try to read until it finds a \0.

So, pass a nul terminated string and everything will be fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top