我有一个程序可以从.raw文件中提取内容,这里有一个示例:
1.000000 1.000000 -1.000000 1.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 -1.000000 1.000000 -1.000000
1.000000 0.999999 1.000000 -1.000000 1.000000 1.000000 -1.000000 -1.000000 1.000000 0.999999 -1.000001 1.000000
1.000000 1.000000 -1.000000 1.000000 0.999999 1.000000 0.999999 -1.000001 1.000000 1.000000 -1.000000 -1.000000
1.000000 -1.000000 -1.000000 0.999999 -1.000001 1.000000 -1.000000 -1.000000 1.000000 - 1.000000 -1.000000 -1.000000
-1.000000 -1.000000 -1.000000 -1.000000 -1.000000 1.000000 -1.000000 1.000000 1.000000 - 1.000000 1.000000 -1.000000
1.000000 0.999999 1.000000 1.000000 1.000000 -1.000000 -1.000000 1.000000 -1.000000 -1.000000 1.000000 1.000000
这些只是一个立方体的面,我的问题是,这个文件是650字节,现在当我加载程序时,程序占用20mb。这不是一个问题,但是当加载更大的文件时,它可能会成为一个大问题。
这是我的文件phraser的代码(对不起,如果它很乱,我是C ++的新手):
/*
* PhraseObj.cpp
*
* Created on: Nov 5, 2011
* Author: tom
*/
#include "PhraseObj.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "obj.h"
PhraseObj::PhraseObj(string file)
{
FILE.open(file.c_str());
cout << FILE.is_open() << "\n";
}
obj PhraseObj::getObj()
{
string line;
Polygon P;
vertex V;
obj O;
int place;
int NextPos;
float x;
float y;
float z;
getline(FILE, line);
while (!FILE.eof()) {
cout << "new line" << "\n";
place = 0;
while (place != string::npos) {
if (place == (line.length() - 1)) {
break;
}
NextPos = line.find(" ", place + 1);
line.substr(place, (NextPos - place) - 1);
cout << line.substr(place, (NextPos - place) - 1).c_str() << " ";
x =::atof(line.substr(place, (NextPos - place) - 1).c_str());
V.x(x);
cout << x << "\n";
place = NextPos;
NextPos = line.find(" ", place + 1);
line.substr(place, NextPos - place);
cout << line.substr(place + 1, (NextPos - place) - 1).c_str() << " ";
y =::atof(line.substr(place + 1, (NextPos - place) - 1).c_str());
V.y(y);
cout << y << "\n";
place = NextPos;
NextPos = line.find(" ", place + 1);
line.substr(place + 1, NextPos - place);
cout << line.substr(place + 1, (NextPos - place) - 1).c_str() << " ";
z =::atof(line.substr(place + 1, (NextPos - place) - 1).c_str());
V.z(z);
cout << z << "\n";
P.addPoint(V);
place = line.find(" ", place + 1);
cout << "place: " << place << " " << "length:" << line.length() << "\n";
}
getline(FILE, line);
O.AddPolygon(P);
}
cout << "returning" << "\n";
try {
return O;
}
catch(bad_alloc & ba) {
cout << "bad_alloc caught: " << ba.what() << endl;
}
}
void PhraseObj::closeFile()
{
FILE.close();
}
bool PhraseObj::isEnd()
{
return FILE.eof();
}
一些注意事项,顶点是x,y和z浮点数 多边形是顶点的矢量 obj是多边形的向量。
谢谢,汤姆。
和vertex.h:
/*
* vertex.h
*
* Created on: Oct 26, 2011
* Author: tom
*/
#ifndef VERTEX_H_
#define VERTEX_H_
class vertex {
float x_;
float y_;
float z_;
public:
//here are some getters
float x() {return x_;} ;
float y() {return y_;} ;
float z() {return z_;} ;
// and now for some setters
void x(float _x) {x_ = _x;} ;
void y(float _y) {y_ = _y;} ;
void z(float _z) {z_ = _z;} ;
};
#endif /* VERTEX_H_ */
和polygon.cpp:
/*
* Polygon.cpp
*
* Created on: Oct 26, 2011
* Author: tom
*/
#include "Polygon.h"
using namespace std;
void Polygon::addPoint(vertex V) {
point.push_back(V);
}
int Polygon::getNumOfPoints() {
return point.size();
}
vertex Polygon::getPoint(int I) {
return point.at(I);
}
答案 0 :(得分:1)
我不知道为什么你会看到过多的内存使用,所以这不是你问题的答案,但我想指出你可以通过以下方式简化你的PhraseObj::getObj()
功能。使用std::istringstream
和std::istream_iterator
个对象:
obj PhraseObj::getObj()
{
obj O;
string line;
while ( getline( FILE, line ) ) {
istringstream vertices( line );
istream_iterator<double> it( vertices ), end;
Polygon p;
for ( int i = 0; i < 4; ++i ) {
Vertex v;
v.x( *it++ );
v.y( *it++ );
v.z( *it++ );
p.addPoint( v );
}
O.AddPolygon( p );
}
}
您可以将字符串粘贴到std::string
对象中,然后使用istringstream
个对象迭代不同的顶点,而不是使用istream_iterator<double>
方法从一个空格字符转到下一个空格字符。如果您知道每行总共有12个坐标顶点(每个顶点有3个顶点,每个多边形有4个顶点),那么您可以使用简单的循环来读取它们。
答案 1 :(得分:1)
从它的外观来看,你的代码并没有那么糟糕。我看到的唯一问题是,你创建了很多中间对象,每个都调用一些内存分配(因为你使用过RAII,好!),这不会导致内存泄漏。但是现代内存分配器不会立即将释放的内存返回给操作系统,而是保留它,以便从那里回答进一步的分配请求。所以你可能只是经历过这一点。
当然,你应该避免创建那些不需要的中间人。例如,您的代码包含大量line.substr(place + 1, NextPos - place);
,您不会将结果字符串分配给任何内容。因此,std::string
变为现实,并且在不被使用的情况下被破坏。
您还应该避免这种过多的调试输出,因为这会严重降低您的程序速度。它可以用于调试目的,但是一旦工作就应该删除或者删除它。
答案 2 :(得分:0)
如果将其保存为浮点数的二进制表示形式,则文件大小,加载时间,解析时间,内存等将显着下降。
只需使用当前的解析器将新文件输出为二进制浮点数(可能创建自定义构建脚本)。然后你可以有一个更小/更快的发行版,并将转换移动到内部。
答案 3 :(得分:0)
我能看到的唯一问题是,您在使用EOF
阅读后正在测试getline()
,您应该使用do ... while更改while循环。除此之外,此代码不是向我们展示的相关代码。可能是多边形和顶点的类声明有很大机会运行内存泄漏......你是否正在使用STL的 vector&lt;&gt; ?
你必须考虑另一件事,因为你还没有告诉你如何得出浪费太多记忆的结论。也许这20 Mb是操作系统中任何进程的标准内存的一部分。如果您想真正了解内存的使用方式,则需要一个分析工具,例如 valgrind 。