C++ Valgrind抱怨使用依赖于未初始化字节的条件跳转

C++ Valgrind抱怨使用依赖于未初始化字节的条件跳转,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)*s

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

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

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

节点内的连接未设置。这是因为您使用malloc来创建您的节点实例。这只会给你未初始化的原始内存。必须使用新的方法来分配C++程序中的对象而不是MALLC。New分配内存,然后运行构造函数

并删除以释放它-不是免费的

实际上,您需要一个节点对象数组。照本说的做。做一个向量


<>但是无论如何,除非你确实知道你在做什么,否则永远不要在C++程序中使用MalC/C。这是因为您使用malloc来创建您的节点实例。这只会给你未初始化的原始内存。必须使用新的方法来分配C++程序中的对象而不是MALLC。New分配内存,然后运行构造函数

并删除以释放它-不是免费的

实际上,您需要一个节点对象数组。照本说的做。做一个向量


<>但是无论如何,在C++程序中永远不要使用MalC/C,除非你确实知道你在做什么[/P>,很可能是因为<代码> MaloC < /C> >不调用<代码>节点< /COD>的构造函数。因为这是C++,节点< /COD>不是一个结构,因为它是C,它是一个类。它有一个隐式构造函数,需要在实例化时调用它。这意味着向量也没有正确创建

你应该做两件事:

  • 避免调用new,在这种情况下没有必要,只需使用
    node A[10]
    或更好的
    std::vector A
  • <>如果你不能做到这一点,在C++中总是使用<代码>新< /Cord>,以便正确创建对象。
    如果绝对必须使用
    malloc
    ,那么无论如何都需要调用
    placement new
    来构造结构(
    new(&A[0])node()
    ),所以确实不要使用
    malloc

    这可能是因为
    malloc
    没有调用
    节点的构造函数。因为这是C++,节点< /COD>不是一个结构,因为它是C,它是一个类。它有一个隐式构造函数,需要在实例化时调用它。这意味着向量也没有正确创建

    你应该做两件事:

  • 避免调用new,在这种情况下没有必要,只需使用
    node A[10]
    或更好的
    std::vector A
  • <>如果你不能做到这一点,在C++中总是使用<代码>新< /Cord>,以便正确创建对象。
    如果绝对必须使用
    malloc
    ,那么无论如何都需要调用
    placement new
    来构造结构(
    new(&A[0])node()
    ),所以确实不要使用
    malloc

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

    malloc
    是分配内存的C方式。它不考虑C++构造函数。
    calloc
    也是C,但它会初始化内存。这就是为什么
    std::vector
    起作用的原因(然而,这也是未定义的行为,因为可能有一个
    vector
    实现需要初始化为零以外的值)

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

    • 改用
      新节点

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

    • 使用智能指针和
      使_共享
      使_唯一
      。这样,你甚至不需要注意释放你的记忆

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


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

    malloc
    是分配内存的C方式。它不考虑C++构造函数。
    calloc
    也是C,但它会初始化内存。这就是为什么
    std::vector
    起作用的原因(然而,这也是未定义的行为,因为可能有一个
    vector
    实现需要初始化为零以外的值)

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

    • 改用
      新节点

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

    • 使用智能指针和
      使_共享
      使_唯一
      。这样,你甚至不需要注意释放你的记忆

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

    因为您使用的是vector,所以应该始终避免malloc和free,因为它们不会初始化构造函数,而是使用new和delete以及智能指针

    然而,很少需要使用new/delete,因为vector用相似的内存和访问空间完成同样的事情

    此实现将
    节点
    包装在一个向量中,并消除了直接内存分配,因为它是由向量自动完成的,同时保持了相同的传统使用方式

    #include <iostream>
    #include <vector>
    using namespace std;
    
    struct node {
        int key;
        vector<int> connections;
    };
    
    int main(void) {
        // original with similar memory footprint and access characteristics using modern C++ vector<>
        int size = 10;
        vector<node> A(size);
    
        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;
            }
        }
        return 0;
    }
    
    #包括
    #包括
    使用namesp
    
    node *A = new Node();
    
    #include <iostream>
    #include <vector>
    using namespace std;
    
    struct node {
        int key;
        vector<int> connections;
    };
    
    int main(void) {
        // original with similar memory footprint and access characteristics using modern C++ vector<>
        int size = 10;
        vector<node> A(size);
    
        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;
            }
        }
        return 0;
    }