Is there a better and fast way to initialize a dynamic array?

Discussion in 'C Programming' started by jerry, Sep 30, 2011.

  1. jerry

    jerry Guest

    Consider the following codes:

    static int POOL_SIZE 256
    static int BUFF_SIZE 1024

    static int *buff_pool[POOL_SIZE]={NULL};

    void init_buff(int idx)
    {
    int i;
    buff_pool[idx]=(int*)malloc(BUFF_SIZE * sizeof(int));
    for (i=0; i<BUFF_SIZE;i+=)
    buff_pool[idx] = 1;
    }

    There is an alternative way is to use memset instead of for loop, but
    it is said that there is no guarantee that the machine representation
    of zero is all-bits-zero. My codes need to work with different
    compiler and machine.

    I wonder if there is a better and fast way to initialize the dynamic
    array without running the whole for loop?

    Thanks

    Jerry
     
    jerry, Sep 30, 2011
    #1
    1. Advertising

  2. jerry

    Ian Collins Guest

    On 10/ 1/11 09:30 AM, jerry wrote:
    > Consider the following codes:
    >
    > static int POOL_SIZE 256
    > static int BUFF_SIZE 1024
    >
    > static int *buff_pool[POOL_SIZE]={NULL};
    >
    > void init_buff(int idx)
    > {
    > int i;
    > buff_pool[idx]=(int*)malloc(BUFF_SIZE * sizeof(int));
    > for (i=0; i<BUFF_SIZE;i+=)
    > buff_pool[idx] = 1;
    > }
    >
    > There is an alternative way is to use memset instead of for loop, but
    > it is said that there is no guarantee that the machine representation
    > of zero is all-bits-zero. My codes need to work with different
    > compiler and machine.
    >
    > I wonder if there is a better and fast way to initialize the dynamic
    > array without running the whole for loop?
    >

    How about:

    enum { POOL_SIZE = 256, BUFF_SIZE = 1024 };

    static int *buff_pool[POOL_SIZE]={NULL};

    typedef struct X { int buf[BUFF_SIZE]; } X;

    static X x;

    void init_buff(int idx)
    {
    buff_pool[idx]=malloc(BUFF_SIZE * sizeof(buff_pool[idx]));

    *(X*)buff_pool[idx] = x;
    }

    int main(void)
    {
    for( int i = 0; i < BUFF_SIZE; x.buf[i++] = 1);

    // stuff.
    }
    --
    Ian Collins
     
    Ian Collins, Sep 30, 2011
    #2
    1. Advertising

  3. jerry

    BartC Guest

    "jerry" <> wrote in message
    news:...

    > There is an alternative way is to use memset instead of for loop, but
    > it is said that there is no guarantee that the machine representation
    > of zero is all-bits-zero. My codes need to work with different
    > compiler and machine.


    If the memory represents pointers or floating point values, then perhaps
    null or 0.0 isn't represented by zeros. But why should it matter for
    integers?

    (And if integer zero doesn't have a representation of all-bits-zero, I don't
    think using assignment is going to help either.)

    --
    Bartc
     
    BartC, Sep 30, 2011
    #3
  4. jerry

    jerry Guest

    On Sep 30, 2:47 pm, Ian Collins <> wrote:
    > On 10/ 1/11 09:30 AM, jerry wrote:
    >
    >
    >
    > > Consider the following codes:

    >
    > > static int POOL_SIZE 256
    > > static int BUFF_SIZE 1024

    >
    > > static int *buff_pool[POOL_SIZE]={NULL};

    >
    > > void init_buff(int idx)
    > > {
    > >    int i;
    > >    buff_pool[idx]=(int*)malloc(BUFF_SIZE * sizeof(int));
    > >    for (i=0; i<BUFF_SIZE;i+=)
    > >        buff_pool[idx] = 1;
    > > }

    >
    > > There is an alternative way is to use memset instead of for loop, but
    > > it is said that there is no guarantee that the machine representation
    > > of zero is all-bits-zero.  My codes need to work with different
    > > compiler and machine.

    >
    > > I wonder if there is a better and fast way to initialize the dynamic
    > > array without running the whole for loop?

    >
    > How about:
    >
    > enum { POOL_SIZE = 256, BUFF_SIZE = 1024 };
    >
    > static int *buff_pool[POOL_SIZE]={NULL};
    >
    > typedef struct X { int buf[BUFF_SIZE]; } X;
    >
    > static X x;
    >
    > void init_buff(int idx)
    > {
    >    buff_pool[idx]=malloc(BUFF_SIZE * sizeof(buff_pool[idx]));
    >
    >    *(X*)buff_pool[idx] = x;
    >
    > }
    >
    > int main(void)
    > {
    >    for( int i = 0; i < BUFF_SIZE; x.buf[i++] = 1);
    >
    >    // stuff.}
    >
    > --
    > Ian Collins- Hide quoted text -
    >
    > - Show quoted text -


    Thanks for your reply.

    It will need an extra memory block to hold the initial value. It also
    need individual initial block for different type, such as long long,
    double, etc. It will increase the memory usage. Considering the
    memory usage, is there a another way?

    Thanks
     
    jerry, Sep 30, 2011
    #4
  5. jerry

    jerry Guest

    On Sep 30, 3:18 pm, "BartC" <> wrote:
    > "jerry" <> wrote in message
    >
    > news:...
    >
    > > There is an alternative way is to use memset instead of for loop, but
    > > it is said that there is no guarantee that the machine representation
    > > of zero is all-bits-zero.  My codes need to work with different
    > > compiler and machine.

    >
    > If the memory represents pointers or floating point values, then perhaps
    > null or 0.0 isn't represented by zeros. But why should it matter for
    > integers?
    >
    > (And if integer zero doesn't have a representation of all-bits-zero, I don't
    > think using assignment is going to help either.)
    >
    > --
    > Bartc


    Thanks for your reply.

    Is it the only way that using assignment for floating array?
     
    jerry, Sep 30, 2011
    #5
  6. jerry

    Ian Collins Guest

    On 10/ 1/11 11:03 AM, jerry wrote:
    > On Sep 30, 2:47 pm, Ian Collins<> wrote:
    >> On 10/ 1/11 09:30 AM, jerry wrote:
    >>
    >>> I wonder if there is a better and fast way to initialize the dynamic
    >>> array without running the whole for loop?

    >>
    >> How about:
    >>
    >> enum { POOL_SIZE = 256, BUFF_SIZE = 1024 };
    >>
    >> static int *buff_pool[POOL_SIZE]={NULL};
    >>
    >> typedef struct X { int buf[BUFF_SIZE]; } X;
    >>
    >> static X x;
    >>
    >> void init_buff(int idx)
    >> {
    >> buff_pool[idx]=malloc(BUFF_SIZE * sizeof(buff_pool[idx]));
    >>
    >> *(X*)buff_pool[idx] = x;
    >>
    >> }
    >>
    >> int main(void)
    >> {
    >> for( int i = 0; i< BUFF_SIZE; x.buf[i++] = 1);
    >>
    >> // stuff.}


    Please don't quote signatures and google nonsense.

    > Thanks for your reply.
    >
    > It will need an extra memory block to hold the initial value. It also
    > need individual initial block for different type, such as long long,
    > double, etc. It will increase the memory usage. Considering the
    > memory usage, is there a another way?


    Life, and programming, is full of compromises. Here the compromise is
    speed/space.

    Is the cost of an initialisation loop a measurable problem to you?

    --
    Ian Collins
     
    Ian Collins, Sep 30, 2011
    #6
  7. On Fri, 30 Sep 2011 13:30:16 -0700 (PDT), jerry <>
    wrote:

    >Consider the following codes:
    >
    >static int POOL_SIZE 256
    >static int BUFF_SIZE 1024
    >
    >static int *buff_pool[POOL_SIZE]={NULL};


    This is a VLA supported only by C99 compilers.

    >
    >void init_buff(int idx)
    >{
    > int i;
    > buff_pool[idx]=(int*)malloc(BUFF_SIZE * sizeof(int));


    Lose the cast. All it does is camouflage an error if you fail to
    include stdlib.h.

    > for (i=0; i<BUFF_SIZE;i+=)


    I assume you meant i++ (or perhaps i+=1).

    > buff_pool[idx] = 1;
    >}
    >
    >There is an alternative way is to use memset instead of for loop, but
    >it is said that there is no guarantee that the machine representation
    >of zero is all-bits-zero. My codes need to work with different
    >compiler and machine.


    Since you don't attempt to assign 0 to any element of the array, what
    difference does it make how zero is represented?

    memset stores values in bytes. If you are attempting to initialize an
    array of char (any flavor) or any other type whose size is 1, it
    should work. If the type has a size greater than one, memset is only
    useful if each byte of an element should have the same value (which
    for practical purposes limits you to integer types with value 0 but
    then you could just as easily use calloc).

    >
    >I wonder if there is a better and fast way to initialize the dynamic
    >array without running the whole for loop?


    I don't know if it is any better but you could reduce the number of
    loop iterations by using memcpy and memmove code along the lines of:

    buff_pool[idx][0] = your value;
    for (i = 1; i < BUFF_SIZE/2; i,, *= 1)
    memcpy(buff_pool[idx],
    buff_pool[idx] + i,
    i * sizeof *buff_pool[idx]);
    memmove(buff_pool[idx],
    buff_pool[idx] + BUFF_SIZE/2,
    (BUFF_SIZE+1)/2 * sizeof *buff_pool[idx]);

    This will work for both non-zero values and non-integer types.

    --
    Remove del for email
     
    Barry Schwarz, Oct 1, 2011
    #7
  8. jerry

    BartC Guest

    "jerry" <> wrote in message
    news:...
    > On Sep 30, 3:18 pm, "BartC" <> wrote:
    >> "jerry" <> wrote in message


    >> > There is an alternative way is to use memset instead of for loop, but
    >> > it is said that there is no guarantee that the machine representation
    >> > of zero is all-bits-zero. My codes need to work with different
    >> > compiler and machine.

    >>
    >> If the memory represents pointers or floating point values, then perhaps
    >> null or 0.0 isn't represented by zeros. But why should it matter for
    >> integers?


    > Is it the only way that using assignment for floating array?


    To initialise a block of floating point numbers to 0.0 where the
    representation is unknown?

    Assignment is the sure way to do it, but that doesn't mean you have to
    assign 0.0 to every element.

    For example, assignment can be used to initialise one row, then memcpy() can
    be used to copy those 0.0s to the other rows.

    And that row can be part of the data, or a special row - or part row - set
    aside for that purpose. There are probably other ways of avoiding too many
    assignments (perhaps using memset() for platforms that you know for sure use
    all-bits-zero, and assignment where that is not the case, using conditional
    compilation)

    --
    Bartc
     
    BartC, Oct 1, 2011
    #8
  9. jerry

    Eric Sosman Guest

    On 9/30/2011 5:18 PM, BartC wrote:
    >[...]
    > (And if integer zero doesn't have a representation of all-bits-zero, I
    > don't think using assignment is going to help either.)


    First, assigning zero -- or forty-two, or negative ninety-nine --
    to an `int' will work just fine, regardless of the representation of
    any of those quantities. You can even safely assign a `signed char'
    with value eighty-six to a `long double' variable and be confident that
    the latter will then have the value eighty-six, even though the two
    representations are almost certainly different.

    Second, any integer type with all-bits-zero has the numerical value
    zero. It may happen that the type has more than one way to represent
    the value zero, but all-bits-zero will be one of them. It may or may
    not be the "normal" way to represent a zero, but a zero it will be.

    (Note that this is only for *integer* types; there is no similar
    guarantee for floating-point, complex, or pointer types.)

    --
    Eric Sosman
    d
     
    Eric Sosman, Oct 1, 2011
    #9
  10. jerry

    Eric Sosman Guest

    On 9/30/2011 6:17 PM, jerry wrote:
    > [... filling an array with a constant ...]
    > Is it the only way that using assignment for floating array?


    It's certainly not the "only" way. For example, you could
    fill element [0] (of an array of any kind at all) manually, then
    use memcpy() to copy [0] to [1], then memcpy() again to copy
    [0] and [1] to [2] and [3], then again to copy [0] through [3]
    to [4] through [7], ... Filling an N-element array this way
    uses approximately lg(N) memcpy() calls, each filling twice as
    many elements as the one before. (Watch out for the boundary
    conditions on the final call, though.)

    However, I urge you to consider Ian Collin's question: "Is
    the cost of an initialisation loop a measurable problem to you?"
    The word "measurable" is of great importance: What have you done
    to obtain evidence that array-filling is a performance problem?
    What have your measurements shown?

    --
    Eric Sosman
    d
     
    Eric Sosman, Oct 1, 2011
    #10
  11. jerry <> writes:
    > Consider the following codes:
    >
    > static int POOL_SIZE 256
    > static int BUFF_SIZE 1024


    Missing semicolons.

    > static int *buff_pool[POOL_SIZE]={NULL};


    That initializes each element of buf_pool to a null pointer.
    The first is explicit, the others are implicit (elements not
    specified in an initializer are initialized to zero converted to
    the appropriate type).

    > void init_buff(int idx)
    > {
    > int i;
    > buff_pool[idx]=(int*)malloc(BUFF_SIZE * sizeof(int));


    Drop the cast.

    > for (i=0; i<BUFF_SIZE;i+=)


    i+= what?

    It would be *really* helpful if you'd post the actual code you compiled,
    copy-and-pasted, not re-typed. Otherwise it can be hard to tell the
    difference between transcription errors and the actual problem you're
    asking about.

    > buff_pool[idx] = 1;
    > }
    >
    > There is an alternative way is to use memset instead of for loop, but
    > it is said that there is no guarantee that the machine representation
    > of zero is all-bits-zero. My codes need to work with different
    > compiler and machine.


    You're setting the elements to 1, not 0. Or was that a typo?

    For integer types, there is a guarantee that all-bits-zero is a
    representation of 0 (though not necessarily the only such
    representation). N1256 6.2.6.2p5:

    For any integer type, the object representation where all the
    bits are zero shall be a representation of the value zero in
    that type.

    (This wasn't in the original C99 standard; it was added in one of the
    Technical Corrigenda, presumably because all existing implementations
    already behaved this way.)

    > I wonder if there is a better and fast way to initialize the dynamic
    > array without running the whole for loop?


    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 1, 2011
    #11
  12. jerry

    Ian Collins Guest

    On 10/ 1/11 12:00 PM, Barry Schwarz wrote:
    > On Fri, 30 Sep 2011 13:30:16 -0700 (PDT), jerry<>
    > wrote:
    >
    >> Consider the following codes:
    >>
    >> static int POOL_SIZE 256
    >> static int BUFF_SIZE 1024
    >>
    >> static int *buff_pool[POOL_SIZE]={NULL};

    >
    > This is a VLA supported only by C99 compilers.


    No, it's an error. You can't declare a VLA at file scope.

    --
    Ian Collins
     
    Ian Collins, Oct 1, 2011
    #12
  13. Keith Thompson <> writes:

    > jerry <> writes:
    >> Consider the following codes:
    >>
    >> static int POOL_SIZE 256
    >> static int BUFF_SIZE 1024

    >
    > Missing semicolons.


    (and = signs)

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Oct 1, 2011
    #13
  14. On Sep 30, 10:30 pm, jerry <> wrote:
    >
    > void init_buff(int idx)
    > {
    >   int i;
    >   buff_pool[idx]=(int*)malloc(BUFF_SIZE * sizeof(int));
    >   for (i=0; i<BUFF_SIZE;i+=)
    >       buff_pool[idx] = 1;
    >
    > }
    >
    > I wonder if there is a better and fast way to initialize the dynamic
    > array without running the whole for loop?
    >

    Not really. On some machines you could set a long or long long to
    0x0000000100000001, then treat buff_pool as a long *, and you might
    initialise the ints faster. But it's very machine specific, and it
    makes the code hard to read. It's very much a last resort.
     
    Malcolm McLean, Oct 1, 2011
    #14
    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.
Similar Threads
  1. milkyway
    Replies:
    1
    Views:
    387
    Collin VanDyck
    Dec 2, 2004
  2. Patrick
    Replies:
    6
    Views:
    8,659
    John C. Bollinger
    Dec 7, 2004
  3. milkyway
    Replies:
    1
    Views:
    664
    Collin VanDyck
    Dec 2, 2004
  4. Paul Rubin
    Replies:
    5
    Views:
    440
    Hendrik van Rooyen
    Aug 6, 2009
  5. DaLoverhino
    Replies:
    1
    Views:
    114
    Uri Guttman
    Sep 9, 2009
Loading...

Share This Page