The Linux program below builds a path by adding some strings to a filesystem path:
#include <filesystem>
int main(int, char**) {
//
std::cout << "Application STARTING\n";
//
fs::path path;
// Add to path
path /= "/media";
path /= "aaa";
path /= "bbb";
// path /= "ccc";
//
std::cout << path.c_str() << std::endl;
//
std::cout << "Application STOPPED\n";
}
If I run this file in valgrind, this is the output:
Application STARTING
/media/aaa/bbb
Application STOPPED
If I uncomment the line that adds "ccc" to the path, compile and run again in valgrind, I get this:
Application STARTING
==2231== Invalid read of size 1
==2231== at 0x4860214: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so)
==2231== Address 0x4d25c17 is 0 bytes after a block of size 31 alloc'd
==2231== at 0x4848744: operator new(unsigned int) (vg_replace_malloc.c:282)
==2231== by 0x4A79CBB: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned int, unsigned int, char const*, unsigned int) (in /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.28)
==2231==
/media/aaa/bbb/ccc
Application STOPPED
I am compiling with these settings:
/usr/bin/arm-linux-gnueabihf-g++ -I/usr/include/alsa -pthread -Wall -Wextra -pedantic -g -DTMTP_DEBUG -std=gnu++17 -o CMakeFiles/tmtp.dir/main.cpp.o -c /media/ssd/projects/tmtp/code/main.cpp
Is this a valgrind error? Am I using the fs::path correctly?
_ UPDATE _
I have reduced to the minimum compiler settings:
/usr/bin/arm-linux-gnueabihf-g++ -g -std=gnu++17 -o CMakeFiles/tmtp.dir/main.cpp.o -c /media/ssd/projects/tmtp/code/main.cpp
I am compiling in C++17 because this allows me to use the non-experimental version of filesystem.
Bad memory read is still reported.
_ ANOTHER UPDATE _
I can create the invalid read error without using filesystem. The code below also reports an invalid read. There are two lines marked in the code, commenting out either removes the invalid read.
#include <iostream>
#include <string.h>
class CPath
{
public:
inline const char* c_str() const { return m_strPath.c_str(); }
inline void operator/=(const char* psz) { append(psz); }
public:
void append(const char* psz)
{
//
m_strPath += '/'; // <--- REMOVE TO PREVENT INVALID READ
m_strPath.append(psz);
}
private:
std::string m_strPath;
};
int main(int, char**) {
//
std::cout << "Application STARTING\n";
//
CPath path;
path /= "media";
path /= "aaa";
path /= "bbb";
path /= "ccc"; // <--- REMOVE TO PREVENT INVALID READ
//
std::cout << path.c_str() << std::endl;
//
std::cout << "Application STOPPED\n";
}