我有这个问题出现在我正在处理的较大程序的模块中,这是一个小模拟:
#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
吗?
不,在这里使用malloc
是不安全的。
malloc
是分配内存的C方式。它不考虑C 构造函数。
calloc
也是C,但它使您的内存零零。这就是std::vector
工作的原因(但是,这也是未定义的行为,因为可能有一个vector
实现,需要将其初始化为零以外的其他功能)。
有很多方法可以解决这个问题:
-
使用
new Node
代替。 -
如果您不能这样做,则至少可以在
malloc
返回的内存上进行新的位置(new (ptr) Node()
)。 -
使用智能指针和
make_shared
或make_unique
。这样,您甚至不需要照顾释放记忆。 -
最好的方法可能是使用
std::vector
(如另一个答案中建议)或std::array
。
由于您使用的是vector&lt;>,因此您应该始终避免使用malloc且免费
但是,很少有需要使用新/删除,因为向量在相似的内存和访问足迹的情况下完成了相同的事情。
此实现将node
包装在向量中,并消除直接内存分配,因为它是通过向量&lt;>自动完成的,同时保持了相同的传统用法样式。
#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;
}
可能是因为malloc
不调用node
的构造函数。由于这是C ,因此node
不是C中的结构,而是一个类。它具有一个隐式构造函数,需要在实例化时调用。这意味着向量也无法正确创建。
您应该做2件事:
- 避免致电新,在这种情况下不需要,只需使用
node A[10]
或更好的std::vector<node> A
。 - 如果您不能这样做,请务必在C 中使用
new
,以便正确创建对象。
如果您绝对必须使用malloc
,则需要调用placement new
以构建您的结构(new (&A[0]) node()
),因此实际上只是不使用malloc
。
未设置节点内的连接。这是因为您使用malloc创建YR节点实例。这只是为您提供了原始的非初始化内存。您必须使用新的来分配C 程序中的对象,而不是Malloc。新的分配内存然后运行构造函数
IE
node *A = new Node();
并删除以释放它 - 不免费
实际上您需要一个节点对象。那做本说的。制作它们的向量
但是,无论如何,除非您真的确定自己在做什么