【问题标题】:C++ Linux string.h invalid read reported in valgrindC++ Linux string.h 在 valgrind 中报告无效读取
【发布时间】:2023-01-12 03:39:18
【问题描述】:

下面的 Linux 程序通过向文件系统路径添加一些字符串来构建路径:

#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";

}

如果我在 valgrind 中运行这个文件,这是输出:

Application STARTING
/media/aaa/bbb
Application STOPPED

如果我取消注释将“ccc”添加到路径的行,编译并在 valgrind 中再次运行,我得到:

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

我正在使用这些设置进行编译:

/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

这是一个 valgrind 错误吗?我是否正确使用了 fs::path?

_ 更新 _

我已经减少到最低编译器设置:

/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

我在 C++17 中编译,因为这允许我使用文件系统的非实验版本。

仍然报告错误的内存读取。

_ 另一个更新 _

我可以在不使用文件系统的情况下创建无效读取错误。下面的代码也报告无效读取。代码中标记了两行,注释掉其中任何一行都可以删除无效读取。

#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";

}

【问题讨论】:

  • 此处显示的代码没有任何问题。因此,问题一定出在此处显然未显示且被排除在外的代码。这就是错误所在。不幸的是,任何人都不可能找出甚至没有显示的代码的问题。仅仅因为程序在这里崩溃并不意味着问题就出在这里。 C++ 不是这样工作的。该错误可能出现在任何地方,但它不会立即崩溃,程序会运行一段时间,然后最终在随机代码行崩溃。
  • 听起来像是您正在使用的标准 C++ 库的错误。
  • 尝试添加这样一行: char* p = new char[8];我怀疑你会得到一个错误。
  • KonstantinL:你是对的。我现在有两个无效读取,我也不知道是什么原因造成的。
  • @Richard,您似乎正在编译禁止动态内存分配的嵌入式软件。

标签: c++ linux valgrind string.h


【解决方案1】:

在使用的嵌入式环境中不允许动态内存分配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-25
    • 1970-01-01
    相关资源
    最近更新 更多