I'm not exactly sure what's happening as I am relatively new to c++
I have globally defined the following above my main loop
vector<Character*> monsters[2][3][6];
vector<Item*> loot[2][3][6];
vector<NPC*> npc[2][3][6];
vector<Objects*> objects[2][3][6];
Inside my Character.h file I have also defined the objects array
extern vector<Objects*> objects[2][3][6];
Everything was working fine until I created the objects array.
It appears that if I add more than 8 objects to the monsters array strange values start appearing into objects and the size of objects increases.
My code is a mess and I'm not sure exactly what I should include here. I hope this is enough to give you an idea of what I'm on about.
I haven't tested this thoroughly so it may very well happen to all of my arrays...
It appears that the monsters array was not large enough so it was "overflowing" and placing objects outside of the array, thus ending up within another array.
Apologies for inconvenience. I hope this helps someone.
Ultimately you want to write your own small Grid class that fits your need or use Boost.MultiArray to handle such cases. Working with nested raw arrays leads to a mess in the long run. Maybe you also want to avoid storing pointers and store objects by value.
Related
Well, after a full year of programming and only knowing of arrays, I was made aware of the existence of vectors (by some members of StackOverflow on a previous post of mine). I did a load of researching and studying them on my own and rewrote an entire application I had written with arrays and linked lists, with vectors. At this point, I'm not sure if I'll still use arrays, because vectors seem to be more flexible and efficient. With their ability to grow and shrink in size automatically, I don't know if I'll be using arrays as much. At this point, the only advantage I personally see is that arrays are much easier to write and understand. The learning curve for arrays is nothing, where there is a small learning curve for vectors. Anyway, I'm sure there's probably a good reason for using arrays in some situation and vectors in others, I was just curious what the community thinks. I'm an entirely a novice, so I assume that I'm just not well-informed enough on the strict usages of either.
And in case anyone is even remotely curious, this is the application I'm practicing using vectors with. Its really rough and needs a lot of work: https://github.com/JosephTLyons/Joseph-Lyons-Contact-Book-Application
A std::vector manages a dynamic array. If your program need an array that changes its size dynamically at run-time then you would end up writing code to do all the things a std::vector does but probably much less efficiently.
What the std::vector does is wrap all that code up in a single class so that you don't need to keep writing the same code to do the same stuff over and over.
Accessing the data in a std::vector is no less efficient than accessing the data in a dynamic array because the std::vector functions are all trivial inline functions that the compiler optimizes away.
If, however, you need a fixed size then you can get slightly more efficient than a std::vector with a raw array. However you won't loose anything using a std::array in those cases.
The places I still use raw arrays are like when I need a temporary fixed-size buffer that isn't going to be passed around to other functions:
// some code
{ // new scope for temporary buffer
char buffer[1024]; // buffer
file.read(buffer, sizeof(buffer)); // use buffer
} // buffer is destroyed here
But I find it hard to justify ever using a raw dynamic array over a std::vector.
This is not a full answer, but one thing I can think of is, that the "ability to grow and shrink" is not such a good thing if you know what you want. For example: assume you want to save memory of 1000 objects, but the memory will be filled at a rate that will cause the vector to grow each time. The overhead you'll get from growing will be costly when you can simply define a fixed array
Generally speaking: if you will use an array over a vector - you will have more power at your hands, meaning no "background" function calls you don't actually need (resizing), no extra memory saved for things you don't use (size of vector...).
Additionally, using memory on the stack (array) is faster than heap (vector*) as shown here
*as shown here it's not entirely precise to say vectors reside on the heap, but they sure hold more memory on the heap than the array (that holds none on the heap)
One reason is that if you have a lot of really small structures, small fixed length arrays can be memory efficient.
compare
struct point
{
float coords[4]
}
with
struct point
{
std::vector<float> coords;
}
Alternatives include std::array for cases like this. Also std::vector implementations will over allocate, meaning that if you want resize to 4 slots, you might have memory allocated for 16 slots.
Furthermore, the memory locations will be scattered and hard to predict, killing performance - using an exceptionally larger number of std::vectors may also need to memory fragmentation issues, where new starts failing.
I think this question is best answered flipped around:
What advantages does std::vector have over raw arrays?
I think this list is more easily enumerable (not to say this list is comprehensive):
Automatic dynamic memory allocation
Proper stack, queue, and sort implementations attached
Integration with C++ 11 related syntactical features such as iterator
If you aren't using such features there's not any particular benefit to std::vector over a "raw array" (though, similarly, in most cases the downsides are negligible).
Despite me saying this, for typical user applications (i.e. running on windows/unix desktop platforms) std::vector or std::array is (probably) typically the preferred data structure because even if you don't need all these features everywhere, if you're already using std::vector anywhere else you may as well keep your data types consistent so your code is easier to maintain.
However, since at the core std::vector simply adds functionality on top of "raw arrays" I think it's important to understand how arrays work in order to be fully take advantage of std::vector or std::array (knowing when to use std::array being one example) so you can reduce the "carbon footprint" of std::vector.
Additionally, be aware that you are going to see raw arrays when working with
Embedded code
Kernel code
Signal processing code
Cache efficient matrix implementations
Code dealing with very large data sets
Any other code where performance really matters
The lesson shouldn't be to freak out and say "must std::vector all the things!" when you encounter this in the real world.
Also: THIS!!!!
One of the powerful features of C++ is that often you can write a class (or struct) that exactly models the memory layout required by a specific protocol, then aim a class-pointer at the memory you need to work with to conveniently interpret or assign values. For better or worse, many such protocols often embed small fixed sized arrays.
There's a decades-old hack for putting an array of 1 element (or even 0 if your compiler allows it as an extension) at the end of a struct/class, aiming a pointer to the struct type at some larger data area, and accessing array elements off the end of the struct based on prior knowledge of the memory availability and content (if reading before writing) - see What's the need of array with zero elements?
embedding arrays can localise memory access requirement, improving cache hits and therefore performance
Now, I need to save a class to a binary file and the problem I ran into when trying to implement this was that the class had members that were actually pointers, so when writing the class to file it only wrote those pointers, not the actual data that the pointers were pointing to.
So what I did was I used malloc() to allocate memory directly when declaring the members within the class. I know that isn't a good thing to do, but I really need to be able to save this class to a binary file.
I could do this easily with char arrays (1 dimensional), but I also have a single 2D int array, and I just can't figure out how to make it allocate enough memory for both dimensions (I know the dimension sizes beforehand). What should I do?
Maybe there's a way to declare static arrays, since I know their sizes beforehand, and then somehow replace them in memory with new ones? I don't know if I can do that, and I don't want to replace elements one by one.
Note: I need the variables to be pointers, because I want to be able to replace their contents later on, instead of having to replace the elements one by one.
I am working on an OpenGL based game, and this problem arises in my search for a robust way to pass entity information to the rendering and networking functions.
Something like this:
vector <DynamicEntity> DynamicEntities;
vector <StaticEntity> StaticEntities;
vector <Entity> *Entities;
Entities.push_back(&DynamicEntities);
Entities.push_back(&StaticEnt);
Graphics.draw(Entities);
Server.bufferData(Entities);
The only information Graphics.draw and Server.bufferData need is contained by Entity, which both DynamicEntity and StaticEntity inherit from.
I know this would work:
vector <Entity*> Entities;
for(uint32_t iEntity=0;iEntity<iNumEntities;iEntity++)
{
Entities.push_back(&DynamicEntities[iEntity])
}
//(ad nauseam for other entity types)
but that seems awfully inefficient, and would have to account for changing numbers of entities as the game progresses. I know relatively little of the underpinnings of data structures; so this may be a stupid question, but I would appreciate some insight.
That copy operation in the for loop you show is likely to be so fast as to be unmeasurable as compared to the cost of drawing the graphics. You may be able to make it faster still by doing Entities.resize(...) before the loop and using array indexing in the loop.
The solution you propose in the first part of your question will not work, because the data layout for a vector<StaticEntity> likely differs from the layout for a vector<DynamicEntity>. Arrays of objects are not polymorphic, and the storage managed by vector<> is essentially an array with some dynamic management around it.
In fact, because the vector storage is array-like, if you replace push_back with array indexing, the body of for loop will compile to something resembling:
*p1++ = p2++;
which the compiler may even auto-vectorize!
I have a problem caused when reserving array. The problem is a heap error. The software i am making is like that:
I am making a small software to render a model of a specific format. the model contains several groups and every group contains array vertices and array of indices for these verts "such as a motorcycle model of 3 groups: front wheel, back wheel and body. After i load the model into memory, i want to render it as a vbo but the model is made of several groups as mentioned. so i am merging all the verts in all groups into one array of verts and the same goes for indices. when merging a heap error occurs when reserving the array. The code is like this:
int index=0;
for(int i=0;i<this->groupsSize;i++)
index+=this->groups[i]->capacity.vertsSize;
mdl_vert *m_pVertices=new mdl_vert[index];
index=0;
for(int i=0;i<this->groupsSize;i++)
index+=this->groups[i]->capacity.indicesSize;
unsigned int *m_pIndices=new unsigned int[index];
index=0;
for(int i=0;i<this->groupsSize;i++)
{
for(int j=0;j<this->groups[i]->capacity.vertsSize;j++)
{
m_pVertices[index]=this->groups[i]->verts[j];
index++;
}
}
When i reserve indices the heap error is occuring. I also used std::vector but the same error occur. can anybody give me a hint of what am i doing wrong in this case.
N.B. mdl_vert is a struct that consists of float x,y,z;caused when reserving array.
You don't supply enough info to pintpoint the problem, or even what the problem is.
But there are things you can do to clean up the code, and maybe that will help.
1. Use std::vector instead of `new`-ing raw arrays
Instead of
unsigned int *m_pIndices=new unsigned int[index];
use
std::vector<unsigned> indices( index );
Note that this std::vector is not itself dynamically allocated.
It uses dynamic allocation inside, and it does that correctly for you.
Even better, just use …
std::vector<int> indices( index );
… because unsigned arithmetic can easily screw up.
2. Don't use misleading naming
The m_ prefix makes it seem as if you really want to access data members, not local variables.
But you are defining local variables.
Either use the data members, or drop the m_ name prefixes.
3. Don't "reuse" variables
You're using the variable index for multiple successive purposes.
Declare and use one (properly named) variable for each purpose.
4. Don't rely on side-effects from earlier code.
For example, you are relying on the value of index after a for-loop where it's used a loop counter.
Instead, directly use the value that you have deduced that it will have.
5. Don't obscure the code with do-nothing things.
This is just a style issue, but consider removing all the this-> qualifications. It's verbose and obscures the code; it makes the code less readable and less clear. Yes, with primitive tools like Visual Studio such qualifications can help with getting names in drop-down lists, but that's a disservice: it makes it more difficult to remember things, and without remembering things you can't have the understanding needed to write correct code.
Cheers & hth.,
How big is the resulting index? Probably just overflow occurs.
Do you know what the error is? If not, you may want to try putting the code into a try/catch with std::exception. Generally when I have gotten errors along those lines, it was related to a st9bad_alloc error. Which essentially means the size supplied to the new was invalid or too big (either in terms or actual memory, or because of limits imposed by the system with regards to stack space). If so, validate the numbers supplied to new, and ensure the stack size is large enough (try the 'limit' command if using Linux). Good luck
One or more of your capacity.indicesSize is likely uninitialized, so you get a way too large number. Print index before allocating
Greetings everyone. This is my first question here at stackoverflow so please bear with me.
My programming class this semester is Java; last semester was C++. My Java teacher feels (justifiably, I think) that it is very important for we students to understand the mechanics of memory management.
Since Java has automatic garbage collection, he has seen fit to give us an assignment in which we must write a very basic program in C++ that creates a two-dimensional array using pointers. Specifically, we are to first create an array of pointers; each pointer in the first array should reference its own array of integers. Then we must deallocate the memory associated with the two arrays.
This assignment is supposed to consist of two functions: one to allocate the 2-D array, and a second to deallocate. I just want to make sure that the following code is logically sound before I proceed.
I'm sure this all seems very simple, but the hitch is that my C++ teacher spent all of two days on pointers. While I somewhat understand the mechanics, I am pretty clueless on implementation. That being said, the following is a very rough start. Is this logically sound? Am I completely off the mark? My most profound thanks in advance for any help.
EDIT: I have created a new question with updated code. You can view it by clicking Here.
When you use
int* i = new int;
you pair it with
delete i;
and when you use
int* i = new int [12];
you pair it with
delete [] i;
If there are brackets in the new, there should be brackets in the delete. Otherwise, your program looks reasonable to me, except that you haven't implemented those two functions that your prof wants you to.
Looks correct to me, with one exception - when you delete arrays you need the following syntax:
delete [] arrayName;
That's a well-asked question.
I don't think I'd call it a "2-D array": it's an array of arrays, not a 2-D array.
I think I'd call my index i or iColumn or iRow instead of nCount (your nRows and nColumns are logically const and used as fencepost/high-water-mark values, whereas your nCount is a loop index).
For bonus points, think about how to test your solution. You can run it to see if it faults ... but the converse, i.e. not faulting, isn't proof that it's correct. What O/S are you running it on? If you're using Linux then a worthwhile test is to run your code using valgrind (because when you run it valgrind can automatically detect a lot of the ways in which it's possible to misuse memory).
You need to use delete [] instead of just delete.
It looks sound(logically).
By the way - it's ok to run a program and have it fail. :-)