Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将未初始化内存分配为C+;时可能出现意外的未定义行为+;容器_C++_Containers_Variable Assignment - Fatal编程技术网

C++ 将未初始化内存分配为C+;时可能出现意外的未定义行为+;容器

C++ 将未初始化内存分配为C+;时可能出现意外的未定义行为+;容器,c++,containers,variable-assignment,C++,Containers,Variable Assignment,如果你编译这个 #include <stdlib.h> #include <vector> using std::vector; int main(){ vector<int> v0,*v1; v1=(vector<int>*)malloc(sizeof(vector<int>)); //cf v1=new vector<int>; v1[0]=v0; while(1); } 这样就不会有

如果你编译这个

#include <stdlib.h>
#include <vector>
using std::vector;

int main(){
    vector<int> v0,*v1;
    v1=(vector<int>*)malloc(sizeof(vector<int>)); //cf v1=new vector<int>;
    v1[0]=v0;
    while(1);
}
这样就不会有编译器警告,它会正常运行,但如果在Valgrind下运行

valgrind --track-origins=yes UB-assignment
它将标记两个未定义的行为警告:

==12668== Conditional jump or move depends on uninitialised value(s)
==12668==    at 0x400A62: std::vector<int, std::allocator<int> >::operator=(std::vector<int, std::allocator<int> > const&) (vector.tcc:185)
==12668==    by 0x400962: main (UB-assignment.cpp:11)
==12668==  Uninitialised value was created by a heap allocation
==12668==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12668==    by 0x40094B: main (UB-assignment.cpp:10)
==12668== 
==12668== Conditional jump or move depends on uninitialised value(s)
==12668==    at 0x400B3A: std::vector<int, std::allocator<int> >::operator=(std::vector<int, std::allocator<int> > const&) (vector.tcc:197)
==12668==    by 0x400962: main (UB-assignment.cpp:11)
==12668==  Uninitialised value was created by a heap allocation
==12668==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12668==    by 0x40094B: main (UB-assignment.cpp:10)
==12668==条件跳转或移动取决于未初始化的值
==12668==at 0x400A62:std::vector::operator=(std::vector const&)(vector.tcc:185)
==12668==by 0x400962:main(UB assignment.cpp:11)
==12668==堆分配创建了未初始化的值
==12668==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==12668==by0x40094b:main(UB-assignment.cpp:10)
==12668== 
==12668==条件跳转或移动取决于未初始化的值
==12668==at 0x400B3A:std::vector::operator=(std::vector const&)(vector.tcc:197)
==12668==by 0x400962:main(UB assignment.cpp:11)
==12668==堆分配创建了未初始化的值
==12668==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==12668==by0x40094b:main(UB-assignment.cpp:10)
为什么会发生这种情况?我意识到不使用malloc可以很容易地避免这个问题,但我希望了解这里发生了什么。我假设问题与破坏未初始化的内存无关,因为无限循环防止它超出范围


(这是与其他容器一起发生的。‘vector’只是一个例子。)

< p>永远不要用任何C++类或标准库容器使用<代码> MalOC 。code>malloc只是在内存中分配一块字节。没别的了
std::vector
有一个必须调用的重要构造函数,否则就是垃圾

您的代码语法正确,因此可以编译。然而,malloced向量是一堆未初始化的值,因为没有调用向量的构造函数

Valgrind在声明中警告您:

v1[0]=v0;

您正在“玩”未初始化的值(即向量的未初始化部分)。导致UB。

您正在使用内存,就好像它包含一个
向量
,而实际上它不包含
向量
(因为您没有发出任何开始向量生命周期的代码)。你只需要malloc一些字节,然后假装一个向量神奇地出现在那个空间中。我没有使用malloced空间作为向量。我只分配给它。我想了解为什么赋值A=B试图使用A作为对象。
A=B
表示
A.operator=(B)
,这是一个函数调用。赋值运算符将执行诸如删除指向包含向量内容的旧内存的指针等操作。@penuniabowl,编译器允许您使用剪刀运行。Valgrind足够聪明,知道你错过了什么,构造器,并且告诉你,“你可以把你的眼睛戳出来。”@M.M它不会试图释放旧的内存,直到向量超出范围,这里没有。(不能,因为可能还有其他引用,C++不使用垃圾收集。)谢谢你的回复,但我不认为它能回答我的问题。显然,malloced内存包含垃圾。我想知道是什么在试图利用作业的LHS。相比之下,这将适用于POD。如果int*a指向未分配内存的sizeof(int)字节,而int b定义了一个真正的int,那么a[0]=b将是一个无问题的赋值。有什么额外的结构使这成为向量的问题?我不想使用它(如问题中所解释的),而是想理解它。Valgrind正在查看分配,并检查分配给LHS的东西。它是从哪里来的?它初始化正确吗?Valgrind发现这从来都不是。很聪明,那很实用。它认识到一个类需要的(构造函数)比一个标量(例如int)更多。你确定吗@donjuedo?Valgrind不是什么风格检查器。它是运行您的程序的虚拟机。在这里,它正在检测std库中实际的未定义行为,我想知道为什么会发生这种情况。Valgrind可以很容易地跟踪内存分配,并知道是否有东西来自malloc(和朋友)。我不知道它使用哪种技术,但在过去,内存调试器会修补新的或malloc,或两者兼而有之。他们可以在返回的指针前面添加元数据,以及其他技巧。
v1[0]=v0;