我有这个问题出现在我正在处理的大型程序的模块中,这是一个小模拟:
#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)
从我的理解中,问题是向量的push_back
函数中有一个if语句,它使用了一些未初始化的值。我不确定到底是什么。玩完之后,问题是我使用malloc
。如果我使用calloc
,我根本不会收到任何警告。如果我使用new
,则相同。但是在所有情况下,程序的行为方式完全相同。这里发生了什么?即使我收到所有这些警告,使用malloc
是否安全?
答案 0 :(得分:2)
不,在这里使用malloc
是不安全的。
malloc
是分配内存的C方式。它没有考虑C ++构造函数。
calloc
也是C,但它会初始化你的记忆。这就是std::vector
工作的原因(然而,它也是未定义的行为,因为可能有一个vector
实现需要初始化为零以外的其他内容。
有很多方法可以解决这个问题:
请改用new Node
。
如果您不能这样做,您至少可以在malloc
返回的内存(new (ptr) Node()
)上进行新的展示位置。
使用智能指针和make_shared
或make_unique
。这样,你甚至不需要照顾你的记忆。
最好的方法可能是使用std::vector
(如另一个答案所示)或std::array
。
答案 1 :(得分:1)
由于您使用的是vector&lt;&gt;,因此您应该始终避免使用malloc和free,因为它们不会初始化构造函数,而是使用new和delete和智能指针。
然而,很少需要使用new / delete,因为vector通过类似的内存和访问占用来实现相同的功能。
此实现将node
包装在向量中并消除直接内存分配,因为它是由vector&lt;&gt;自动完成的。同时保持相同的传统使用方式。
#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;
}
答案 2 :(得分:0)
未设置节点内的连接。这是因为您使用malloc来创建您的Node实例。这只是给你原始的未初始化的内存。你必须使用new来分配c ++程序中的对象而不是malloc。 New分配内存然后运行构造函数
即
node *A = new Node();
并删除以释放它 - 不是免费的
实际上你需要一个Node对象数组。那样做是什么意思。制作一个矢量
但无论如何,除非你确定你知道自己在做什么,否则永远不要在c ++程序中使用malloc / free
答案 3 :(得分:0)
可能是因为malloc
没有调用node
的构造函数。由于这是c ++,node
不是c中的结构,它是一个类。它有一个隐式构造函数,需要在实例化时调用。这意味着矢量也未正确创建。
你应该做两件事:
node A[10]
或更好std::vector<node> A
。new
,以便正确创建对象。如果你绝对必须使用malloc
,那么你需要调用placement new
来构建你的结构(new (&A[0]) node()
),所以真的不要使用malloc
。