use*_*437 3 c++ memory-management vector object
我有一个程序,它创建了大量的对象并将它们插入到一个向量中.我的想法是创建大约10,000个对象,但我发现该程序在几千个之后崩溃了.在崩溃之前创建的对象数量是随机的,取决于我是否修改了代码中的任何行,所以我认为是一个与内存分配有关的问题.
我正在创建的对象是这样的:
class Object {
public:
//Needed by map
Object() {
}
Object(int newID, std::string newText) {
id = newID;
text = newText;
}
int getID() {
return id;
}
std::string getText() {
return text;
}
~Object() {
}
private:
int id;
std::string text;
};
Run Code Online (Sandbox Code Playgroud)
没有什么特别的,正如你所看到的.创建对象的程序如下:
int main(int argc, char** argv) {
int numberOfElements;
long start;
long end;
long time1, time2, time3, time4, time5, time6;
numberOfElements = 7000; //7000<X<7050 Maximum reliable
{
//Measuring time for creation of 1000 elements in vector of objects,
cout << "VECTOR OF OBJECTS:" << endl;
start = getTimeInMicroseconds();
vector<Object> vectorOfObjects;
vectorOfObjects.reserve(10000);
for (int i = 0; i < numberOfElements; i++) {
cout << "Creating object " << i << endl;
Object object = *(new Object(i, "This is object "+i));
cout << "Created object " << i << endl;
vectorOfObjects.push_back(object);
cout << "Object inserted" << endl;
}
end = getTimeInMicroseconds();
time1 = end - start;
cout << "- Time to create " << numberOfElements << " objects = "
<< time1 << " microseconds" << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
再一次,非常简单.崩溃前创建的对象数量取决于我在此代码之后添加的内容.有时它在2000之后崩溃,有时在4000之后,有时在7000之后崩溃......我想这是一个内存分配问题,但我不知道如何解决它.
我尝试将对象创建为:
Object object(i, "text");
vectorOfObjects.push_back(object);
vectorOfObjects.push_back(Object(i, "text");
vectorOfObjects.push_back(*(new Object(i, "text")));
Run Code Online (Sandbox Code Playgroud)
但他们都没有工作.当然,我更喜欢一种动态创建这些对象的方法,就像我在这里展示的最后两个例子; 我也尝试使用不同的容器,例如map或deque,但由于问题的发生是因为对象的创建而不是因为容器本身,所以我使用哪个容器并不重要.
这是核心转储:
-bash-3.2$ pstack core
core 'core' of 5884: ./datastructuresperformance
d147646c strlen (8046eb8, 8055000, 8046ebc, d17c34ed) + c
08051fdf main (1, 8047264, 804726c, 8051ddf) + f7
08051e27 _start (1, 80473b8, 0, 80473d4, 80473ef, 8047441) + 67
-bash-3.2$ pmap core
core 'core' of 5884: ./datastructuresperformance
08044000 16K rwx-- [ stack ]
08050000 20K r-x-- /export/home/dcs/SolStudioProjects/DataStructuresPerformance/dist/Release/OracleSolarisStudio-Solaris-x86/datastructuresperformance
08064000 8K rwx-- /export/home/dcs/SolStudioProjects/DataStructuresPerformance/dist/Release/OracleSolarisStudio-Solaris-x86/datastructuresperformance
08066000 280K rwx-- [ heap ]
D1450000 1088K r-x-- /lib/libc.so.1
D1560000 32K rwx-- /lib/libc.so.1
D1568000 8K rwx-- /lib/libc.so.1
D1570000 292K r-x-- /lib/libm.so.2
D15C8000 16K rwx-- /lib/libm.so.2
D15D0000 48K r-x-- /usr/lib/libCrun.so.1
D15EB000 8K rwx-- /usr/lib/libCrun.so.1
D15ED000 20K rwx-- /usr/lib/libCrun.so.1
D1600000 24K rwx--
D1610000 1244K r-x-- /usr/lib/libCstd.so.1
D1750000 4K rwx--
D1756000 216K rwx-- /usr/lib/libCstd.so.1
D1790000 4K rwx--
D17A0000 4K rw---
D17B0000 4K rw---
D17BF000 176K r-x-- /lib/ld.so.1
D17F0000 4K rwx--
D17FB000 8K rwx-- /lib/ld.so.1
D17FD000 8K rwx-- /lib/ld.so.1
total 3532K
Run Code Online (Sandbox Code Playgroud)
它不应该是与内存量有关的问题,因为到目前为止该程序使用的最大内存量远低于本机的1GB.
seh*_*ehe 12
*new T()被称为内存泄漏操作员.你不想动态分配一个Object,相反,你只想构造一个(用矢量破坏)"string" + i因为它会对char(&)[7](即"string")进行指针运算.从逻辑上讲,"string" + i说&("string"[i]),这会导致不确定的行为(在你的情况下,崩溃)当i是>比字符串文本的长度.new除非你知道你在做什么,否则不要在C++中使用:
Object object = Object(i, "This is object " + to_string(i));
Run Code Online (Sandbox Code Playgroud)
更好的是,emplace_back如果您的编译器不是很老,请考虑使用:
vector<Object> vectorOfObjects;
vectorOfObjects.reserve(100000000ul);
for(int i = 0; i < numberOfElements; i++) {
vectorOfObjects.emplace_back(i, "This is object " + to_string(i));
}
Run Code Online (Sandbox Code Playgroud)
(对不起,被那条线吓了一跳:/)
Object object = *(new Object(i, "This is object "+i));
Run Code Online (Sandbox Code Playgroud)
不要那样做.永远.试试这个:
Object object(i,"This is object");
Run Code Online (Sandbox Code Playgroud)
该行有两个问题:
a)你实际做的是创建一个对象,复制它然后忘记它.
b)(这是崩溃你的代码的东西) - 给它一个字符串,从i字节前面的字节开始,而不是字符串"This is Object".你可以想象,你的内存不是免费的.