   c++'s "new" clarification
  i really need a refresher on what the "new" operator does and most importantly does not do.the reason i want to know is because when trying to create a .3ds loader fuction i wanted to use dynamic arrays to store the vertex coordinates, polygon vertex numbers, and mapping coordinates.  the reason i thought this would work is because the .3ds file format stores the count of each one of those properties.  however, once i had my function written i noticed that when i wanted to display all those triangles the program would crash (before every displaying a single frame so i narrowed it down to the display function).  so with some fiddling i found out that i could only display at max 176 polys from the dynamic array.  this bothered me to say the least so i went back to the tried and true method of over allocating space with constants.  but then i'm back to where i didn't want to be -- creating a class with over allocated space.so my question is this -- is there a way to allocate the space dynamically other than the new operator?  if there is, is there a way to make sure it is contiguous for proper use as an array?  and if there isn't a way other than the "new" operator, how can i make sure that the array is going to get the space it needs?  or more imporantly, should i even bother with the dynamic implementation and just stick with static declerations?and for reference (if my explanation at 4:30am isn't too clear :) ) here is an example code snipet://original structstypedef struct{  float x, y, z;}vertex_type;typedef struct{  int a, b, c;}polygon_type;typedef struct{  float u, v;}mapcoord_type;typedef struct{  vertex_type* vertex;  polygon_type* polygon;  mapcoord_type* mapcoords;  int numvertices;  int numpolygons;}obj_type;//the current obj_type struct which is the only one to changetypedef struct{  vertex_type vertex[20000];  polygon_type polygon[15000];  mapcoord_type mapcoords[20000];  int numvertices;  int numpolygons;}obj_type;// an example of the original loading code (this is for loading polygon data,// the others are very similar with only small changes, mostly referenced from // spacesimulator.net)case 0x4120:  fread (&l_quantity, sizeof (unsigned short), 1, l_file);  testobj.numpolygons = l_quantity;  testobj.polygon = new polygon_type[l_quantity]; // <- this is now commented out   for (i=0; i<l_quantity; i++) // since there is no need for the "new" operator with   {   // the predetermined array size    fread (&testobj.polygon.a, sizeof (unsigned short), 1, l_file);    fread (&testobj.polygon.b, sizeof (unsigned short), 1, l_file);    fread (&testobj.polygon.c, sizeof (unsigned short), 1, l_file);    fread (&l_face_flags, sizeof (unsigned short), 1, l_file);  }break;
  That all seems fine to me. new and new[] will allocate a contiguous block of memory large enough to hold the object or array of objects requested, and will then call the constructor or constructors of all elements in the array.The only other portable way to allocate memory is malloc(), but that's C and won't call constructors. There are other platform specific routines too, but that's overkill for this.You should stick with new[], there must be a problem elsewhere in your code.   ;Quote:Original post by supercat1so my question is this -- is there a way to allocate the space dynamically other than the new operator?Why don't you want to use new ?int* ptr = new int[42]; // allocates memory for 42 intsQuote:or more imporantly, should i even bother with the dynamic implementation and just stick with static declerations?Large arrays on the stack == just don't do it.;Quote:Original post by FrunyQuote:or more imporantly, should i even bother with the dynamic implementation and just stick with static declerations?Large arrays on the stack == just don't do it.Would you mind explaining why?;  precisely!  i don't want that overhead because it is just so wastefull.but about the issue in the code -- i don't believe that it is in the loading function at all.  i ruled that out fairly early because when i printed all the vertex and polygon data to the screen it worked perfectly fine and i had all 13k+ polys, 11k+ verts, and i didn't bother to check the mapcoords because there were no textures yet.  however, there was one consistant issue -- the first two values of the polygon input (for polygon[0].a and polygon[0].b) were huge values that weren't indexes for the vertex array.  this is what caused my program to crash i found out, so the fix for that was to make the display loop i=1 instead of i=0 (the side effect being that one poly wasn't there).  however then i discovered the size limitation.  and i have no idea what caused that.i'm gonna go test this again see if maybe it will work now..........my computer just made a liar out of me.  sometimes i really don't know why some errors show up at times and not others.  i'll blame the early hour and dev-cpp and not myself.  :)  in other words, it all works now!  tomorrow's goal -- put in lights and try not to make a post and look stupid.  :Dthanks for afirming what i thought about the new operator and i really don't know what i did to change anything.here is the new poly reading function though:case 0x4110: // this reads the vertex data, it works just fine as far as i can tell  fread(&l_quantity, sizeof(unsigned short), 1, l_file);  testobj.numvertices = l_quantity;  testobj.vertex = new vertex_type[l_quantity];for(i = 0; i < l_quantity; i++)  {    fread(&testobj.vertex.x, sizeof(float), 1, l_file);    fread(&testobj.vertex.y, sizeof(float), 1, l_file);    fread(&testobj.vertex.z, sizeof(float), 1, l_file);  }  break;   case 0x4120:  fread (&l_quantity, sizeof (unsigned short), 1, l_file);  testobj.numpolygons = l_quantity;  testobj.polygon = new polygon_type[l_quantity];  for (i=0; i<l_quantity; i++)  {    fread (&spaceeater, sizeof (unsigned short), 1, l_file);    testobj.polygon.a = spaceeater;    fread (&spaceeater, sizeof (unsigned short), 1, l_file);    testobj.polygon.b = spaceeater;    fread (&spaceeater, sizeof (unsigned short), 1, l_file);    testobj.polygon.c = spaceeater;// these are the original assignment statements//    fread (&testobj.polygon.a, sizeof (unsigned short), 1, l_file);//    fread (&testobj.polygon.b, sizeof (unsigned short), 1, l_file);//    fread (&testobj.polygon.c, sizeof (unsigned short), 1, l_file);    fread (&l_face_flags, sizeof (unsigned short), 1, l_file);  }  break;;Quote:Original post by EzbezQuote:Original post by FrunyQuote:or more imporantly, should i even bother with the dynamic implementation and just stick with static declerations?Large arrays on the stack == just don't do it.Would you mind explaining why?Because there is a limit to the size of the stack for a program.int main(){int m[300000];printf("Hello there");return 0;}When I try to run this program, the program crashes. But when I run it with "int* m = new int[300000];" instead, it runs just fine.Even if you don't allocate enough at a single time to cause a crash, since the stack is used for keeping track of all the local variables and return addresses (the address of the function to return to after a function has finished running), if you allocate a lot on the stack, you might be fine for a while, but after that allocation, as the call stack gets deeper and deeper, you could crash simply by entering a function, even if the function is fairly trivial (like a single 'printf' call).The max I've ever allocated on the stack was a a kilobyte, and that was for a string I was using to read in from a text file. Basically if you need something larger than that, you should really think about dynamic allocation.   ;  Your code practically pure C code, not C++.  C++ gives us a better set of tools to work with.  In particular it gives us the class std::vector, which is a dynamic array class which handles memory management and keeps track of its size.  Its much less error-prone than manually handling memory management and length tracking yourself.To use a std::vector you must include the header <vector>.  std::vector is a template class, so to declare a vector of X you say std::vector< X >.  A vector of vertex_type is therefore std::vector< vertex_type >.  vector supports array indexing just like raw arrays and the memory is guaranteed to be contiguous, so you can take a pointer to the first element (providing the vector is not empty) and treat the result just like a pointer to a raw array.  To get the number of elements stored in a vector you can use the size() member function.So, using std::vector, and with a few other changes, you code would become:// the typedef struct idiom is unneccessary in C++.struct vertex_type{  float x, y, z;};struct polygon_type{  // name your variables expressively  int vertex_1_index, vertex_2_index, vertex_3_index;};// C++ uses streams for I/O.  One advantage of stream objects is that you// can provide overloads of the stream operators to load and save objects// of user defined typesstd::istream & operator>>(std::istream & stream, polygon_type & polygon){  // you can't just read two bytes into a four byte type and expect things  // to work, so read into a two byte type and assign into the four byte  // type to get guaranteed correct behaviour.  unsigned short value;  stream.read(reinterpret_cast< char * >(&value), sizeof (unsigned short));  testobj.polygon.vertex_1_index = value;  stream.read(reinterpret_cast< char * >(&value), sizeof (unsigned short));  testobj.polygon.vertex_2_index = value;  stream.read(reinterpret_cast< char * >(&value), sizeof (unsigned short));  testobj.polygon.vertex_3_index = value;}struct mapcoord_type;{  float u, v;};struct obj_type{  // vectors replace pointers to raw arrays  std::vector< vertex_type > vertices;  std::vector< polygon_type > polygons;  std::vector< mapcoord_type > mapcoords;};// an example of the original loading code (this is for loading polygon data,// the others are very similar with only small changes, mostly referenced from // spacesimulator.net)case 0x4120:  // C++ uses streams for I/O.  One advantage of stream objects is that they  // automatically close themselves when they go out of scope  file_reader.read(reinterpret_cast< char * >(&l_quantity), sizeof (unsigned short));  // an efficiency optimisation - we know how many polygons there are going to  // be so we can preallocate sufficient memory to hold them all and avoid  // additional reallocations  testobj.polygons.reserve(l_quantity);  for (i = 0; i < l_quantity; ++i)  {    polygon_type polygon;    // read a polygon from the file    file_reader >> polygon;    // append the polygon onto the end of the vector    testobj.polygons.push_back(polygon);    stream.read(reinterpret_cast< char * >(&l_face_flags), sizeof (unsigned short));  }break;Σnigma   ;  ah, now i had considered using the vector class however, i believe what it does is that whenever it needs to resize it actually will double its size by creating a new array and copying everything to that.  i personally am not a fan of the vector (or many of the stl) classes because i can't be sure it is behaving how i want it to behave.also, your "reserve" call is no more efficient than calling the "new" operator.  in fact, i believe that it is less space efficient because you have the vector class over head.i agree, many of c++'s stream operating tricks are nice (and i use them in my school projects all the time), however, i'm not in the state of mind to track down any errors when writing them.  :)  also, like i said in my comments, much of this code is derived from spacesimulator.net because it has the best tutorial on how to load data from a .3ds file.  the one draw back to that tutorial is it only deals with loading vertices, polygon vertex indices, and u/v coordinates when in fact the .3ds file will also tell you the texture name and many other wonderful things. :)so, yeah, i know it isn't great c++ in that area, but the rest of my code is pretty much true c++.  plus, i'm developing on dev-c++ and it seems to behave the best with these functions.having said that, if i were to go back and redo this whole thing i would probably do exactly what you had written -- true c++ style (except without the vector class for the reasons i stated above).   ;Quote:Original post by supercat1ah, now i had considered using the vector class however, i believe what it does is that whenever it needs to resize it actually will double its size by creating a new array and copying everything to that.  i personally am not a fan of the vector (or many of the stl) classes because i can't be sure it is behaving how i want it to behave.Not being sure of how the STL behaves isn't a good reason to avoid it. However, it is a good reason to learn how the STL actually does works. You can a learn great deal about algorithm and data structure design by reading the source of an STL implementation.Quote:Original post by supercat1also, your "reserve" call is no more efficient than calling the "new" operator.  in fact, i believe that it is less space efficient because you have the vector class over head.More efficient - no, but it is safer, easier, and less prone to memory leaks than the code you write yourself.The overhead for most std::vector implementations is 12 bytes per vector. When you are dealing with ten thousand triangles - I hardly think it matters eh?   ;  In modern OS, it is the OS who allocate the memory for the applications running. So, if you really don't want to use the new syntax in C++, you can call up the OS specific API. For example in Win32, you can call HeapAlloc(), GlobalAlloc().Though, with the above methods, you need to help managing the memory with the OS and there is a lack of flexability in the OS to optimize the physical and virtual memory.For C++ specific construct like inheritance and virtual function, the new syntax will help calling the appropriate auto generated codes to prepare the vtable.   