Author Topic: Possible Relatively Simple Way To Do Dynamic Multi-Dimensional Arrays In C Or C+  (Read 14818 times)

0 Members and 1 Guest are viewing this topic.

Offline James C. Fuller

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 595
  • User-Rate: +11/-8
Fred,
  Doesn't this zero ?

this->pObjs=new datatype[iNumElements]();

James

Offline Frederick J. Harris

  • Hero Member
  • *****
  • Posts: 914
  • User-Rate: +16/-0
    • Frederick J. Harris
I'm pretty sure not James.  I could be wrong about it.  You might want to check it out.  I believe there may be a distinction there between creation of POD types, i.e., Plain Old Data, and class types.  That's exactly the point I was trying to make.  I haven't done an internet search on it or anything like that (I did think of asking at www.cplusplus.com), but I just haven't.  The reason I posted though what I did is because of my results from my applications I've been working with.  When I was doing that #define stuff, I was having to do the memset thing on my ints.  In fact, I had a nasty bug about it.  What happened was that my tables like I posted above a few posts were coming out with massive errors, i.e., numbers like so ...

3453214567 in many fields that should have been zeros or small numbers like 3420, etc.  I mean a bad mess up.  No crashes or anything, just very bad results.  And what I tracked it down to was that when I was doing the memset thing on the allocated memory I was forgetting to add the sizeof(int) to my multiplication of the bytes to multiply by.  For example, if I wanted 4 rows by 3 cols I'd need this to null it out ...

memset(pInts,0,4*3*sizeof(int));

and this is what I had ...

memset(pInts,0,4*3);

See, I'm not a big user of new.  Usually I use the Win32 memory allocation functions like HeapAlloc(), GlobalAlloc(), etc.  Those functions want the number of bytes you want allocated - not the number of some kind of object.  Of course, to use that memory after successfully acquiring it, it must be cast to some variable type the compiler is aware of.  But C++'s new wants the number of objects - not the number of bytes.  So to null out memory returned by C++'s new, you'll need to multiply the number of objects times the sizeof each object.  In my case above, after I fixed my expression - no more bogus data.

Where the plot thickens is several days ago, in working with this stuff, I tried to  create an array of std::string objects.  I posted some of that code using my string class and the std::string class several posts back.  In doing that I immediately got instant GPFs with the std::string class.  I was bewildered.  So I started putting printf statements all over the class code to try to determine where it was crashing.  Where it was crashing was in the destructor calls.  All of a sudden the bells, sirens, and whistles went off when it dawned on me that when any class is instantiated, the compiler immediately executes constructor calls on the object.  In C++ if there is a default constructor supplied, the compiler uses that one; if not it provides its own.  In any case, every cell in the array will contain a default object on which the constructor was called.  If, as my code would do with the memsets in place, it went through it and nulled out all that memory, it would all then be corrupted in terms of the existing classes there - I think.  That seemed to be the case.  When I removed those memset calls - it worked perfectly. 

Now, in your case, you are doing what I'm doing with vectors, and the code for all that is somewhere in the C++ Standard Libraries.  They may handle that situation there for you.  You may not need to do this for your vector based arrays.  I simply don't know that.  But for my technique, it looks like I need to handle it as I've said in my last post.

Now another issue here is RTTI, i.e., runtime type information.  If my premise is correct, I could solve it within my class by determining what type of object is being created, i.e., a POD type or a non-POD type (Plain Old Data).  Again, if my premise is correct, POD types need zeroed out - not non-POD types.  You have seen that acronym, haven't you?  I see it in error messages all the time.

Thoughts???  I mean, you are the one with the big red book! :)

Offline Frederick J. Harris

  • Hero Member
  • *****
  • Posts: 914
  • User-Rate: +16/-0
    • Frederick J. Harris
In the application I'm working with the result of failing to zero out the memory if the data type is an array of ints created with new is about as subtle as a sledgehammer.  The top table is the correct result, and the bottom one is without zeroing out the memory...

Code: [Select]

                          Overall Totals For All Sawtimber

Dbh       RM        RO        BO        SO        WO        CO        YP       Totals
=====================================================================================
12         0       303         0         0         0         0         0          303
13         0         0         0         0         0         0         0            0
14         0         0       518         0         0         0         0          518
15         0         0         0         0         0         0         0            0
16         0         0         0       853         0         0         0          853
17         0         0         0         0         0         0         0            0
18         0         0         0         0       892         0         0          892
19         0         0         0         0         0         0         0            0
20         0         0         0         0         0      1237         0         1237
21         0         0         0         0         0         0         0            0
22      1274         0         0         0         0         0         0         1274
23         0         0         0         0         0         0         0            0
24         0         0         0         0         0         0       843          843
=====================================================================================
        1274       303       518       853       892      1237       843         5920




                          Overall Totals For All Sawtimber

Dbh       RM        RO        BO        SO        WO        CO        YP       Totals
=====================================================================================
12         0 285212992     24237   7212800   7220040         0         0    299670069
13     24237   7212800   7220040         0         0         0         0    249338115
14         0  33619971 134242481   7209011   7220040         0         0    182291503
15     24230   7212800   7220040         0         0         0         0    115120372
16         0         0         0       857     24249   7209104   7209104     14443314
17   7209016   7221248     53248         0         0         0         0     21692528
18         0         0         0         0       892         0         0          892
19         0         0         0         0         0         0         0            0
20         0         0         0         0         0      1237         0         1237
21         0         0         0         0         0         0         0            0
22      1274         0         0         0         0         0         0         1274
23         0         0         0         0         0         0         0            0
24         0         0         0         0         0         0       843          843
=====================================================================================
     7214074       303       518 335545193     25129   7214037   7220883      7215076

See what I mean?

Offline James C. Fuller

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 595
  • User-Rate: +11/-8
Fred,
  This zeros mem with the () but does not without it but it is a POD.

James

Code: [Select]
#include <iostream>
using namespace std;

int main ()
{
    char*    mem;

    int      i;
    //mem = new  char[ 500];
    mem = new  char[ 500]();
    for(i = 0; i <= 499; i += 1)
    {
        if(mem[i] != 0 )
        {
            cout << " i = " << i << endl;
            cout << to_string(mem[i]) << endl;
            break;
        }
    }

    cout << "done!  with i = " << i << endl;
    delete []mem;

}


Offline Frederick J. Harris

  • Hero Member
  • *****
  • Posts: 914
  • User-Rate: +16/-0
    • Frederick J. Harris
Wow!  You're teaching me something new James.  I've never seen that syntax before.  When I saw the '()' in your post above I thought it was a typo.  That's why I didn't address it.  I just did a quick search on new and the only reference I could find to an empty set of parentheses, i.e., '()', after new and '[]' was for allocating an array of function pointers.  Do you have a link to where you learned that, or is it in your new red book?  Or could it be a new C++11 feature I don't know about???

Offline James C. Fuller

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 595
  • User-Rate: +11/-8
Fred,
  I Googled c++ new zero initialize and got this as one of hits:

http://stackoverflow.com/questions/7546620/operator-new-initializes-memory-to-zero

James

Offline Frederick J. Harris

  • Hero Member
  • *****
  • Posts: 914
  • User-Rate: +16/-0
    • Frederick J. Harris
Hmmmm.  I'll have to continue with it tomorrow.  About all programmed out for today.  I was wondering if that was working off the same idea as that empty bracket syntax for structs.  I imagine you've seen it; I've used it but not much, for example something like so...

WNDCLASSEX wc={};

I think that's right.  It initializes the struct members to 0.  But those aren't brackets, but rather () you are using I think.

Offline Patrice Terrier

  • ROMs
  • Hero Member
  • *****
  • Posts: 936
  • User-Rate: +62/-1
    • www.zapsolution.com
Easy dynamic array is already available from the core API, its name is LISTBOX

I use it a lot to keep my code small without messing with all the memory allocation problems (especially in 64-bit).
And i can access it from everywhere using just GetDlgItem.  :)

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline James C. Fuller

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 595
  • User-Rate: +11/-8
Hmmmm.  I'll have to continue with it tomorrow.  About all programmed out for today.  I was wondering if that was working off the same idea as that empty bracket syntax for structs.  I imagine you've seen it; I've used it but not much, for example something like so...

WNDCLASSEX wc={};

I think that's right.  It initializes the struct members to 0.  But those aren't brackets, but rather () you are using I think.

Fred,
  With bc9Basic translation I always use {0} to initialize; and yes () with new.

James