multiarray

Discussion in 'C++' started by Thunder, Nov 10, 2006.

  1. Thunder

    Thunder Guest

    How can I declare a array as bool slice[x][y][z];
    I want declare this in a class member.
    Thanks.
    Thunder, Nov 10, 2006
    #1
    1. Advertising

  2. Thunder wrote:
    > How can I declare a array as bool slice[x][y][z];
    > I want declare this in a class member.


    So, what's the problem with just declaring it as 'bool slice[x][y][z]'?

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Nov 10, 2006
    #2
    1. Advertising

  3. Thunder

    Default User Guest

    Thunder wrote:

    > How can I declare a array as bool slice[x][y][z];
    > I want declare this in a class member.
    > Thanks.



    What are x,y,z? Give some detail as to what you want to do. Have you
    tried something? What problems did you have? Is this supposed to be a
    dynamic array?



    Brian
    Default User, Nov 10, 2006
    #3
  4. Thunder

    Thunder Guest

    Default User ha scritto:

    > Thunder wrote:
    >
    > > How can I declare a array as bool slice[x][y][z];
    > > I want declare this in a class member.
    > > Thanks.

    >
    >
    > What are x,y,z? Give some detail as to what you want to do. Have you
    > tried something? What problems did you have? Is this supposed to be a
    > dynamic array?



    x,y,z are parameters of function member.Yes It's a dynamic array.

    I want to do something as this.
    void func()
    {
    int sx=....
    int sy=....
    int sz=....
    slice=new [sx] [sy] [sz];
    }

    My problem is the following I don't know as I should declare array
    slice in member class,
    and I don't know as allocate memory for this array.
    Thunder, Nov 10, 2006
    #4
  5. Thunder

    Default User Guest

    Thunder wrote:

    >
    > Default User ha scritto:
    >
    > > Thunder wrote:
    > >
    > > > How can I declare a array as bool slice[x][y][z];
    > > > I want declare this in a class member.
    > > > Thanks.

    > >
    > >
    > > What are x,y,z? Give some detail as to what you want to do. Have you
    > > tried something? What problems did you have? Is this supposed to be
    > > a dynamic array?

    >
    >
    > x,y,z are parameters of function member.Yes It's a dynamic array.
    >
    > I want to do something as this.
    > void func()
    > {
    > int sx=....
    > int sy=....
    > int sz=....
    > slice=new [sx] [sy] [sz];
    > }


    Well, you can't do that. See the FAQs:

    <http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.16>

    You could do it like this:

    int ***slice;

    slice = new int**[sx];

    for(int i = 0; i < sx; i++)
    {
    slice = new int*[sy];
    for(int j = 0; j < sy; j++)
    slice[j] = new int[sz];
    }

    I recommend nesting std::vectors. Easier and less prone to problems.
    I'd also look hard at the design that requires a three-dimensional
    array.


    > My problem is the following I don't know as I should declare array
    > slice in member class,


    That's not your problem, it's a design decision, but won't affect how
    things are declared and defined.

    > and I don't know as allocate memory for this array.


    That's your big problem. Figure that out first, then figure out where
    it goes.




    Brian
    Default User, Nov 10, 2006
    #5
  6. Thunder

    BobR Guest

    Default User wrote in message ...
    >Thunder wrote:
    >> Default User ha scritto:
    >> > Thunder wrote:
    >> > > How can I declare a array as bool slice[x][y][z];
    >> >
    >> > What are x,y,z?

    >>
    >> x,y,z are parameters of function member.Yes It's a dynamic array.
    >>
    >> I want to do something as this.
    >> void func(){
    >> int sx=....
    >> int sy=....
    >> int sz=....
    >> slice=new [sx] [sy] [sz];
    >> }

    >
    >Well, you can't do that. See the FAQs:
    ><http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.16>
    >
    >You could do it like this:
    >
    >int ***slice = new int**[sx];
    >for(int i = 0; i < sx; i++){
    > slice = new int*[sy];
    > for(int j = 0; j < sy; j++)
    > slice[j] = new int[sz];
    > }
    >
    >I recommend nesting std::vectors. Easier and less prone to problems.
    >I'd also look hard at the design that requires a three-dimensional
    >array.


    Another idea:

    {
    cout<<"\n --- VecBit test ---"<<std::endl;
    size_t const bits(3);
    std::vector< std::bitset<bits> > VecBit( 7, 4 ); // 3x7 init to 4

    VecBit.at(0)[0] = true;
    VecBit.at(1)[1] = true;
    VecBit.at(2) = 5;
    VecBit.at(3) = 7;
    VecBit.at(4) >>= 1;
    std::bitset<bits> more;
    VecBit.push_back( more ); // add more
    for(size_t i(0); i < VecBit.size(); ++i){
    cout<<"VecBit.at("<<i<<")="<< VecBit.at(i) <<std::endl;
    } //for(i)
    size_t x(2), y(1), z(0);
    if( VecBit.at(2)[y] ){ // if( VecBit.at(2).at(1) ) // no .at() for bitset
    cout<<"true"<<std::endl;
    }
    else{
    cout<<"false"<<std::endl;
    }
    cout<<" x="<<std::boolalpha<<VecBit.at(2)[x]
    <<" z="<<VecBit.at(2)[z]<<std::endl;
    cout<<" --- VecBit test ---end\n"<<std::endl;
    }
    /* --- VecBit test ---
    VecBit.at(0)=101
    VecBit.at(1)=110
    VecBit.at(2)=101
    VecBit.at(3)=111
    VecBit.at(4)=010
    VecBit.at(5)=100
    VecBit.at(6)=100
    VecBit.at(7)=000
    false
    x=true z=true
    --- VecBit test ---end
    */

    --
    Bob R
    POVrookie
    BobR, Nov 11, 2006
    #6
  7. Thunder:

    > How can I declare a array as bool slice[x][y][z];


    I've seen elsethread that you're talking about dynamic allocation. You
    could try something like the following:

    #include <cstddef>

    template<class ArrElemT>
    class Arr3D {
    private:

    typedef std::size_t size_t;

    size_t const s1,s2;

    ArrElemT *const p;

    public:

    Arr3D(size_t const a,size_t const b,size_t const c)
    : s1(b*c),s2(c),p(new ArrElemT[a*b*c]) {}

    ~Arr3D() { delete [] p; }

    ArrElemT &GetElem(size_t const a,size_t const b,
    size_t const c)
    {
    return *(p + a*s1 + b*s2 + c);
    }
    };


    #include <iostream>
    #include <cstdlib>

    int main()
    {
    std::size_t x,y,z;

    std::cin >> x >> y >> z;

    if (x<5 || y<5 || z<5) return EXIT_FAILURE;

    Arr3D<double> obj(x,y,z);

    obj.GetElem(4,4,4) = 89.234;
    }

    --

    Frederick Gotham
    Frederick Gotham, Nov 13, 2006
    #7
  8. Frederick Gotham:


    > Arr3D(size_t const a,size_t const b,size_t const c)
    > : s1(b*c),s2(c),p(new ArrElemT[a*b*c]) {}



    That would be better as:

    new ArrElemT{a*s1)

    --

    Frederick Gotham
    Frederick Gotham, Nov 13, 2006
    #8
  9. Frederick Gotham:

    > new ArrElemT{a*s1)



    (, not {.

    --

    Frederick Gotham
    Frederick Gotham, Nov 13, 2006
    #9
  10. Thunder

    Gavin Deane Guest

    Frederick Gotham wrote:
    > Thunder:
    >
    > > How can I declare a array as bool slice[x][y][z];

    >
    > I've seen elsethread that you're talking about dynamic allocation. You
    > could try something like the following:
    >
    > #include <cstddef>
    >
    > template<class ArrElemT>
    > class Arr3D {
    > private:
    >
    > typedef std::size_t size_t;
    >
    > size_t const s1,s2;
    >
    > ArrElemT *const p;
    >
    > public:
    >
    > Arr3D(size_t const a,size_t const b,size_t const c)
    > : s1(b*c),s2(c),p(new ArrElemT[a*b*c]) {}
    >
    > ~Arr3D() { delete [] p; }
    >
    > ArrElemT &GetElem(size_t const a,size_t const b,
    > size_t const c)
    > {
    > return *(p + a*s1 + b*s2 + c);
    > }
    > };


    A copy constructor and assignment operator are also needed, or it those
    operations need to be disabled.

    Gavin Deane
    Gavin Deane, Nov 13, 2006
    #10
  11. Thunder

    Gavin Deane Guest

    Frederick Gotham wrote:
    > Frederick Gotham:
    >
    >
    > > Arr3D(size_t const a,size_t const b,size_t const c)
    > > : s1(b*c),s2(c),p(new ArrElemT[a*b*c]) {}

    >
    >
    > That would be better as:
    >
    > new ArrElemT{a*s1)


    I think it is clearer as you had it originally.

    Gavin Deane
    Gavin Deane, Nov 13, 2006
    #11
  12. Frederick Gotham wrote:
    >
    >> new ArrElemT{a*s1)

    >
    >
    > (, not {.
    > ...


    That way you'd make your code to depend critically on the order of class
    data member declaration. If someone accidentally (or intentionally)
    changed the order to

    ...
    ArrElemT *const p;
    size_t const s1,s2;
    ...

    the initialization would fail. That's one thing to remember about
    initialization lists.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Nov 13, 2006
    #12
  13. Gavin Deane:

    >> That would be better as:
    >>
    >> new ArrElemT{a*s1)

    >
    > I think it is clearer as you had it originally.



    Yes, I would agree that it is clearer, but efficiency takes precedence for me
    99% of the time (i.e. the code only evaluates "b*c" once rather than twice).

    --

    Frederick Gotham
    Frederick Gotham, Nov 13, 2006
    #13
  14. Andrey Tarasevich:

    > That way you'd make your code to depend critically on the order of class
    > data member declaration. If someone accidentally (or intentionally)
    > changed the order to
    >
    > ...
    > ArrElemT *const p;
    > size_t const s1,s2;
    > ...
    >
    > the initialization would fail. That's one thing to remember about
    > initialization lists.



    I remember one time a few years back, I was writing some C++ code. I think I
    changed compiler, or maybe simply upgraded compiler, but when I re-compiled
    my program after the install, I got a new warning telling me that the
    initialisation list order didn't match the declaration order. This was the
    first I had heard of it! My intuition at the time made me assume that they're
    initialised in order of their appearance in the initialisation list.

    Which begs the question...

    Why is it determined by declaration order rather than initialition list
    order? The latter would seem to make _a lot_ more sense.

    --

    Frederick Gotham
    Frederick Gotham, Nov 13, 2006
    #14
  15. Thunder

    werasm Guest

    Frederick Gotham wrote:

    > Why is it determined by declaration order rather than initialition list
    > order? The latter would seem to make _a lot_ more sense.


    Does a class require a constructor? - No
    Does a class require a definition? - Yes
    Need a member be initialised in the member initialiser list? - No
    Need a member be defined to be a member? - Yes.

    I suppose there are more reasons, but the above seems to be reasons for
    me. I do agree that a good compiler can (perhaps should) warn about
    this, especially when there is some form of interdependence.

    Another thing to consider is, is it right to provide weak associations
    at construction time, or should the be realized after construction? Any
    thoughts on this?

    My thoughts are, requiring weak associates to exist at construction
    time imposes more restrictions on the client. Usually (IME) the setting
    of weak associations do not involve the possibility of exceptions. I do
    not see why they have to be specified in the member initialiser list.
    Giving the client an option is always good, but that could involve
    writing many constructors. Ownership, of course is another matter.

    Regards,

    Werner
    werasm, Nov 14, 2006
    #15
  16. Frederick Gotham wrote:
    > ...
    > Why is it determined by declaration order rather than initialition list
    > order? The latter would seem to make _a lot_ more sense.
    > ...


    There is an important rule strictly followed in most of C++: objects
    must be destructed in the order that is reverse of the order of their
    construction. This rule applies to class subobjects as well.

    If C++ allowed "custom" subobject construction order (determined by
    constructor initialization list, for example), compilers would have to
    memorize that order at run-time for each object somehow, and then use it
    later in each object's destructor in order to satisfy the
    reverse-order-destruction requirement. That would take certain amount of
    additional housekeeping data in each object and more complicated
    housekeeping code in constructors and destructors. In order to avoid all
    these extra expenses the order of construction (and destruction) was
    made pre-determined at compile-time by the order of subobject declaration.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Nov 14, 2006
    #16
  17. Thunder

    Gavin Deane Guest

    Frederick Gotham wrote:
    > Gavin Deane:
    >
    > >> That would be better as:
    > >>
    > >> new ArrElemT{a*s1)

    > >
    > > I think it is clearer as you had it originally.

    >
    >
    > Yes, I would agree that it is clearer, but efficiency takes precedence for me
    > 99% of the time (i.e. the code only evaluates "b*c" once rather than twice).


    Fair enough. That's up to you. There is also Andrey Tarasevich's point
    that your constructor becomes critically reliant on the order of member
    object declarations not changing.

    For the benefit of the OP, if you are programming in a collaborative
    environment (ie working with other programmers on the same project),
    professionally or otherwise, your fellow programmers will not, in
    general, thank you for sacrificing readability in this kind of way.
    Their ability to do their job (ie develop and maintain code without
    introducing bugs) depends on their ability to read all the code they
    are working on - theirs and yours. If you are programming on your own,
    you can, of course, do whatever you like.

    Gavin Deane
    Gavin Deane, Nov 14, 2006
    #17
  18. Andrey Tarasevich:

    > If C++ allowed "custom" subobject construction order (determined by
    > constructor initialization list, for example), compilers would have to
    > memorize that order at run-time for each object somehow, and then use it
    > later in each object's destructor in order to satisfy the
    > reverse-order-destruction requirement.



    My first thought was: So why not just use the initialisation list order
    rather than the declaration order, when it occurred to me: You can have
    more than one constructor, and therefore more than one initialisation list,
    and therefore more than one order in which to construct the sub-objects.

    Am I right in thinking that this is the reason why they went with
    declaration order?

    Anyhow, I suppose we'll just have to do with comments:

    class Whatever {
    private:

    /* Don't change the declaration order below! */
    int a;
    double b;
    char *c;
    /* Don't change the declaratino order above! */

    };

    --

    Frederick Gotham
    Frederick Gotham, Nov 14, 2006
    #18
  19. Gavin Deane:

    > For the benefit of the OP, if you are programming in a collaborative
    > environment (ie working with other programmers on the same project),
    > professionally or otherwise, your fellow programmers will not, in
    > general, thank you for sacrificing readability in this kind of way.



    If they're that heart broken, we can give them comments:

    new ArrElemT[a*s1] /* s1 == b*c */

    --

    Frederick Gotham
    Frederick Gotham, Nov 14, 2006
    #19
  20. Thunder

    Gavin Deane Guest

    Frederick Gotham wrote:
    > Gavin Deane:
    >
    > > For the benefit of the OP, if you are programming in a collaborative
    > > environment (ie working with other programmers on the same project),
    > > professionally or otherwise, your fellow programmers will not, in
    > > general, thank you for sacrificing readability in this kind of way.

    >
    >
    > If they're that heart broken, we can give them comments:
    >
    > new ArrElemT[a*s1] /* s1 == b*c */


    Indeed. Whenever performance considerations require you to obfuscate
    your code, the next best thing is documentation to clarify your reasons
    and intent.

    Gavin Deane
    Gavin Deane, Nov 15, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page