# Boost Regex fails to be instantiated

This topic is 2714 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, I'm trying to use boost::regex to parse a .ASE file. However, the boost::regex class fails to instantiate somewhere in the middle of the parsing.
Here is some of my code:
 //the actual parsing method void Mesh::LoadASE() { sptr<SubMesh> submesh; int nVertices, nFaces; std::string::const_iterator bound; Vec3 vtemp, vpos; Mat33 mtransform; Reader reader(FileName); //jump into the first submesh reader.JumpAfterNext("GEOMOBJECT"); while(!reader.eof()) { reader.JumpAfterNext("NODE_TM"); //get the name of the submesh reader.JumpAfterNext("NODE_NAME"); //generate a new submesh submesh=sptr<SubMesh>(new SubMesh(reader.GetQuotedString())); //get the matrix transform reader.JumpAfterNext("TM_ROW0"); mtransform.setRow(0, reader.GetVec3()); reader.JumpAfterNext("TM_ROW1"); mtransform.setRow(1, reader.GetVec3()); reader.JumpAfterNext("TM_ROW2"); mtransform.setRow(2, reader.GetVec3()); //get the position reader.JumpAfterNext("TM_ROW3"); vpos=reader.GetVec3(); //get buffer sizes reader.JumpAfterNext("MESH_NUMVERTEX"); nVertices=reader.GetInt(); submesh->VertexBuffer=Buffer<real>(nVertices*3); submesh->NormalBuffer=Buffer<real>(nVertices*3); submesh->TextCoordBuffer=Buffer<real>(nVertices*2); //get index buffer size reader.JumpAfterNext("MESH_NUMFACES"); nFaces=reader.GetInt(); submesh->IndexBuffer=Buffer<unsigned int>(nFaces*3); //get the vertices for(int i=0;i<nVertices;i++) { reader.JumpAfterNext("MESH_VERTEX"); reader.JumpAfterNext("\\d+"); vtemp=reader.GetVec3(); submesh->Verticies.push_back(vtemp); } //get the indices for(int i=0;i<nFaces;i++) { reader.JumpAfterNext("MESH_FACE"); reader.JumpAfterNext(":"); for(unsigned int j=0;j<3;j++) //Fails somewhere here submesh->IndexBuffer.p[i*3+j]=reader.GetInt(); } //get the texCoords reader.JumpAfterNext("MESH_NUMTVERTEX"); nVertices=reader.GetInt(); for(int i=0;i<nVertices;i++) { reader.JumpAfterNext("MESH_TVERT"); for(unsigned int j=0;j<2;j++) submesh->TextCoordBuffer.p[i*2+j]=reader.GetReal(); } SubMeshes.push_back(submesh); //jump to next submesh reader.JumpAfterNext("GEOMOBJECT"); } } //one of the Reader parsing functions real Reader::GetReal() { //init the regex vars boost::regex expression("(\\-?[\\d|\\.]+)"); //This is where it fails at some point std::string::const_iterator start=CurPos, end=File.end(); boost::match_results<std::string::const_iterator> matches; boost::match_flag_type flags = boost::match_default; //get the real real r; if(boost::regex_search(start, end, matches, expression, flags)) { start=matches[0].second; string str=std::string(matches[1].first, matches[1].second); r=string::alphaToReal(str); } CurPos=start; return r; } 

I posted only one of the parsing functions, but that's because they are all the same. I basically duplicated the regex creating code in every single one of them and just altered the info extraction block.
As you can see, the LoadASE fails to create boost::regex somewhere around the middle, at index extraction. If I comment out the index extraction block, it will fail somewhere later. Can I not mindlessly instantiate the boost::regex classes over and over? Or is the problem somewhere else? Thank you.

##### Share on other sites

 real Reader::GetReal() { //init the regex vars boost::regex expression("(\\-?[\\d|\\.]+)"); //This is where it fails at some point std::string::const_iterator start=CurPos, end=File.end(); boost::match_results<std::string::const_iterator> matches; boost::match_flag_type flags = boost::match_default; //get the real real r; if(boost::regex_search(start, end, matches, expression, flags)) { start=matches[0].second; string str=std::string(matches[1].first, matches[1].second); r=string::alphaToReal(str); } CurPos=start; return r; } 

When in doubt, pull out the part that you think is failing in to a tiny self-contained program. It's much easier to debug and explain that way. Do I need to care about the rest of your code here?

Are you sure you need to escape "-" with a preceding "\\" in your expression? By default boost::regex uses Perl syntax and according to this, hyphens don't need to be escaped.

As you can see, the LoadASE fails to create boost::regex somewhere around the middle, at index extraction.
[/quote]
What does this mean? A crash? A compilation error? An exception? If so, what kind?

If I comment out the index extraction block, it will fail somewhere later.
[/quote]
Again, "fail" has not been defined.

Can I not mindlessly instantiate the boost::regex classes over and over?
[/quote]
This shouldn't be a problem.

##### Share on other sites
Sorry for the confusion. Fail means heap corruption. It throws a Heap Dbg exception. Also, if I use boost::regex::assign instead of creating a boost regex copy, the effect is the same: the heap gets corrupted.
I have actually found the source of the problem - as always, I screwed something up, though I'm not sure what.

I have a class Buffer<T> that is a lightweight array container. Here is it's code:
 template<typename T> class Buffer { public: Buffer(int size=0) { Size=size; if(size) p=new T[Size]; else p=0; }; Buffer(std::vector<T> &vec) { Size=vec.size(); if(Size) { p=new T[Size]; for(unsigned int i=0;i<vec.size();i++) p=vec.size; } else p=0; }; Buffer(Buffer &buffer) { if(buffer.Size&&buffer.p) { Size=buffer.Size; p=new T[Size]; for(unsigned int i=0;i<Size;i++) p=buffer; } else Size=p=0; }; ~Buffer() { if(p) delete[] p; }; T *p; unsigned int Size; }; 
This is the IndexBuffer, VertexBuffer and TextCoorBuffer class you can see in the previous code.
I switched to std::vectors instead and everything works fine (Except being slow as hell). This class, however, does not and I really can not tell why. It often fails to instantiate the pointers properly and then to release the memory, resulting in crashes when I try to exit the program.
This is the class that causes heap corruption. What's wrong with it?

##### Share on other sites
In the constructor from an std::vector, surely you mean p = vec, not p = vec.size? This constructor should also take the vector argument by const reference.

The copy constructor should also take a Buffer by const reference.

You have omitted the operator[] for your buffer, so I can't critique that. This could be where the problem is.

You're missing an assignment operator, either in your code, or because you've neglected to show it here. You'll really need one of those if you don't have it already. EDIT: I now notice that you are indeed assigning Buffer objects in your code. I strongly suspect this is the cause of your problem.

Semi-colons aren't needed after the closing brace of method definitions.

You might not want to hear this, but I'd simply stick with std::vector. It's designed to be as efficient as possible. If you can write a replacement that's faster you're either not using vector correctly, or you should file a bug report with the STL implementor. Check that you don't have your standard library's debugging features enabled.

Have you run your code in a debugger? Can you find the line where the problem occurs?

##### Share on other sites
The debug line occurs at the destructor: delete[] p;. Every time that it happens the compiler tells me that the content of the pointer is unreadable (even though Size is set to something real and the pointer must have been instantiated).
I do not have an assignment operator, I thought that the automatic operator should work fine.
The Buffer(std::vector&) hasn't been used yet - it obviously would never compile with such stupid mistakes.
As far as using std::vector goes, it takes me about 3 second to parse a .ASE file with about 400 vertices. I can't say if it's because of the std::vector or because of bad regex usage or if it's even acceptable. I guess I'll stick to std::vectors for now, but I'm still curious about what mistake have I made.

##### Share on other sites

I do not have an assignment operator, I thought that the automatic operator should work fine.

It doesn't.

Consider carefully what happens when you do this:

 Buffer<int> b1(100); Buffer<int> b2(200); b2 = b1; // b2 destructor called // b1 destructor called 

First of all, in the assignment you've lost a handle on the 200 ints that b2 held before. Memory leak. Second, b1.p and b2.p now point to the same location. b2's destructor will delete[] that pointer and b1's destructor will delete[] it again.

I recommend reading about the rule of 3. That article actually implements something similar to your Buffer as an illustrative example. Knowing about the copy-and-swap idiom is also useful in this regard.

EDIT: If you're using Visual C++, it's probably worth googling for _SECURE_SCL and _HAS_ITERATOR_DEBUGGING.

##### Share on other sites
Ok, I see. I guess I'll follow that rule from now on. Thank you very much for your help.

1. 1
2. 2
3. 3
4. 4
Rutin
16
5. 5

• 12
• 9
• 12
• 37
• 12
• ### Forum Statistics

• Total Topics
631415
• Total Posts
2999965
×