c++ - Valgrind 提示使用依赖于未初始化字节的条件跳转

标签 c++ valgrind

这个问题出现在我正在处理的一个较大程序的模块中,这里是一个小模拟:

#include <iostream>
#include <vector>

using namespace std;

struct node{
    int key;
    vector<int> connections;
};

int main(void){

    int size = 10;
    node *A;

    A=(node*)malloc((size)*sizeof(node));

    int i;
    for(i=0;i<size;i++){
        A[i].key = i;
        if(i%2 == 0) A[i].connections.push_back(i);
    }

    for(i=0;i<size;i++) {
        if(A[i].connections.size() > 0) {
            cout << A[i].key << "---" << A[i].connections.size() << endl;
        }
    }

    free(A);

    return 0;
}

这是我在运行 valgrind ./testCode 时得到的一小部分

==30433== Conditional jump or move depends on uninitialised value(s)
==30433==    at 0x400F63: std::vector<int, std::allocator<int> >::push_back(int const&) (stl_vector.h:915)
==30433==    by 0x400DF0: main (testCode.cpp:25)

根据我的理解,问题在于 vector 的 push_back 函数中有一个 if 语句使用了一些未初始化的值。我不确定到底是什么。玩了一下,发现问题出在我使用了malloc。如果我使用 calloc 我根本不会收到任何警告。如果我使用 new 也是一样。然而,在所有情况下,程序的行为方式完全相同。这里发生了什么?即使收到所有这些警告,使用 malloc 是否安全?

最佳答案

不,这里使用malloc是不安全的。

malloc 是分配内存的 C 方式。它不考虑 C++ 构造函数。

calloc 也是 C,但它会零初始化您的内存。这就是 std::vector 起作用的原因(然而,它也是未定义的行为,因为可能有一个 vector 实现需要初始化为非零的其他值)。

有很多方法可以解决这个问题:

  • 改用新节点

  • 如果您不能这样做,您至少可以在 malloc 返回的内存上做一个新的放置 (new (ptr) Node())。

  • 使用智能指针和make_sharedmake_unique。这样,您甚至不需要关心释放内存。

  • 最好的方法可能是使用 std::vector(如另一个答案中所建议的)或 std::array

    <

关于c++ - Valgrind 提示使用依赖于未初始化字节的条件跳转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41268913/

相关文章:

c++ - 具有类型别名的循环依赖

c++ - 将深拷贝构造函数添加到 std::unique_ptr<my_type>

c++ - Valgrind 下 Mac OS 上的 std::thread.join() SIGSEGV

c++ - 我应该压制吗?如果是这样如何从 Makefile 中抑制

linux - Valgrind ARM 二进制文件在 ARM926EJ 中不工作,给出错误未找到

c++ - 在 Eclipse 中向 'link' 命令添加引号

C++ 函数模板格式化

c++ - 将 lambda 推送到 C++ STL 队列导致段错误

c - GTK hello_world 程序中的内存泄漏

cmake - 如何让 ctest 在没有 dart 的情况下使用 valgrind 运行程序?