std::vector whose type is a locally defined struct -- could this be done in a better way?

I am using a std::vector whose type is a locally defined struct. The program compiles fine and testing the compiled program in the console shows that the variables are properly stored. Visual Studio's debugger doesn't seem to recognize the vector's type and it's contents though (so long as they are locally defined), unless I define the struct globally. So this got me thinking and even though it's working outside the debugger I'm wondering if what I'm doing could be structured in a better way.

I am reading data from a file that is in XML format. I store the data in a series of arrays that get dynamically allocated at runtime, once I determine the number of elements and sub-elements that are stored in the file. I tried to avoid using std::vectors in order to avoid the memory overhead, as the files store 3D data meant for rendering and each of the files can store very large amounts of data that get virtually no addition or subtraction of elements after their initialization.

So the only advantage of using vectors is that they can be dynamically increased in size, and this would be a helpful feature in this case only in the following way: because the file format does not specify the amount of elements or sub-elements but just sequentially presents it until the end of the file is reached. For this reason, I decided that using std::vectors as an intermediate format would make it easier to store simply those numbers of elements that represent my array sizes, and then just allocate the memory for my arrays and read the data in. So I used something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct geometryElementTemp //temporarilly stores a <geometry> element
	{
		int sourceElements; // number of <source> sub-elements
		int primitiveTypeElements; // number of <triangles> sub-elements, etc
		
		geometryElementsTemp(): sourceElements(0), primitiveTypeElements(0) 
		{}		
	};

vector<geometryElementTemp> TemporaryGeometryElementsVector;

geometryElementTemp tempGeomElement; //used to store data for single <geometry> element 
//until it is pushed_back in TemporaryGeometryElementsVector

// ...
// program reads file, sets the values for tempGeomElement.sourceElements
// and tempGeomElement.primitiveTypeElements
// ...

//attempts to push_back tempGeomElement
TemporaryGeometryElementsVector.push_back(tempGeomElement);


Like I said, the above works fine even in the debugger, provided I define the struct (geometryElementTemp) globally. If I try to define it locally, the assignment of values to tempGeomElement works fine in the debugger but the std::vector's type or contents don't show up -- the contents show up as "???". The compiled program prints the proper values to screen though.

The reason I avoid making it global is that I intend to only use it as an intermediary way to store my array sizes without making multiple reading passes through the file. And since it is not reusable or otherwise useful, I'd like not to add it in my headers etc, so for all these reasons I thought that I could define it within the scope of my file-reading function.

Is this unorthodox or not advisable in some way, do you think it should be done differently?

Any feedback is most welcome. Thanks in advance, I appreciate it.

Ogoyant


Last edited on
local types can only be used as template parameters since C++11, so it's possible that your Visual Studio's debugger isn't yet familiar with this language feature.

it is not reusable or otherwise useful, I'd like not to add it in my headers etc

The usual appropriate place for such local types is the unnamed namespace, that is, in your cpp file,
1
2
3
namespace {
// your structs, functions, variables, etc
}


using std::vectors as an intermediate format would make it easier to store simply those numbers of elements that represent my array sizes, and then just allocate the memory for my arrays and read the data in.

That seems counterintuitive. Why use arrays at all?
I see, thank you Cubbi, I appreciate the feedback.

So if I did something such as this:
1
2
3
4
5
6
7
namespace {

        struct geometryElementTemp //temporarilly stores a <geometry> element
	{
		//struct variables etc.	
	};
}


the struct would be visible only in that specific cpp file, if I understand this correctly (I haven't used unnamed namespaces so far). That would be pretty appropriate I guess, for something like this.

That seems counterintuitive. Why use arrays at all?

Well, my file format presents the content without specifying the number of elements and sub-elements, like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<geometry>
	<source>...</source>
	<source>...</source>
	<source>...</source>
	<triangles>...</triangles>
</geometry>

<geometry>
	<source>...</source>
	<triangles>...</triangles>
	<quads>...</quads>
</geometry>

<geometry>
	<source>...</source>
	<triangles>...</triangles>
</geometry>

// etc. , until the end of the file 


Since a file can have from 1-any number of <geometry> elements, and each <geometry> element can have from 0-any number of sub-elements, I figured that I would do the following: essentially store the content in two passes, make a first pass through the file where I skip the actual data and only store the number of <geometry> elements and the number of each type of sub-element (so that the std::vector and my struct only store the number of elements and sub-elements, not any of the actual data). And then once I know the number of elements in the file, allocate the required memory (mostly arrays of floats and ints) and make a second pass through the file, this time storing the actual data in the allocated arrays (which are kept for rendering, while the vector that stored the number of elements is deleted at this point).

It would be definitely easier and simpler to store all the data in a single pass using vectors, but the reason I wanted to use arrays is in order to avoid the overhead by std::vector::capacity compared to std::vector::size. For example, the sample program on this site for vector::capacity compares a vector of 100 elements and shows that the capacity actually has allocated 141 elements for prospective addition of elements to the vector. ( http://www.cplusplus.com/reference/stl/vector/capacity/ ). So I figured that for storing (at least) thousands of polygon-related elements that will not receive any addition or subtraction of elements after their creation, using std::vectors would lead to an immense memory overhead for no reason or advantage.

If you have any suggestions on my approach or I seem to misunderstand the overhead issue I'd certainly appreciate the feedback though.

Thanks in advance, I appreciate the input.

Ogoyant
Last edited on
Topic archived. No new replies allowed.