Static memory overrun help

Discussion in 'C++' started by spoc, Aug 30, 2004.

  1. spoc

    spoc Guest

    I am using VC++6 and Numega bounds checker and have been getting many STATIC
    MEMORY OVERRUN errors (boundschecker) while trying to track down bugs. An
    example is below:

    void func()
    {
    static int midSection[ 10 ][ 10 ];

    memset(&midSection, 0, sizeof(midSection));
    }

    For the life of me I can't see why this should cause an error. I also get
    the error for the following:


    void func()
    {
    static char f[ 100 ];

    strcpy(f, funcb() ); // where funcb() is guaranteed to return a string <
    100
    }

    Maybe it's just bounds checker? Anyone help?
     
    spoc, Aug 30, 2004
    #1
    1. Advertising

  2. spoc wrote:
    > I am using VC++6 and Numega bounds checker and have been getting many STATIC
    > MEMORY OVERRUN errors (boundschecker) while trying to track down bugs. An
    > example is below:
    >
    > void func()
    > {
    > static int midSection[ 10 ][ 10 ];
    >
    > memset(&midSection, 0, sizeof(midSection));
    > }
    >
    > For the life of me I can't see why this should cause an error. I also get
    > the error for the following:
    >
    >
    > void func()
    > {
    > static char f[ 100 ];
    >
    > strcpy(f, funcb() ); // where funcb() is guaranteed to return a string <
    > 100
    > }
    >
    > Maybe it's just bounds checker? Anyone help?


    There is nothing in this code that would suggest memory overrun. However,
    if you intended to just _initialise_ 'midSection' in the first 'func', you
    shouldn't memset it every time the function runs. You just need to do

    static int midSection[10][10] = { 0 };

    which initialises it to 0s. Although, IIRC, even that is unnecessary due
    to the fact that all objects of static storage duration are zero-
    initialised anyway. Again, that's if you just needed it to initialise. If
    you do need it cleaned up every time, your code is fine.

    If I were to nit-pick, I'd change

    memset(&midSection, ...

    to

    memset(&midSection[0][0], ...

    but it really shouldn't make any difference in the execution because the
    address of an array and the address of the first element of the array are
    the same (although their types are different).

    Victor
     
    Victor Bazarov, Aug 30, 2004
    #2
    1. Advertising

  3. spoc

    ma740988 Guest

    [....]
    >
    > If I were to nit-pick, I'd change
    >
    > memset(&midSection, ...
    >
    > to
    >
    > memset(&midSection[0][0], ...
    >
    > but it really shouldn't make any difference in the execution because the
    > address of an array and the address of the first element of the array are
    > the same (although their types are different).
    >

    Could you elaborate on the type differences here? I think I'm
    following you but ....

    > Victor
     
    ma740988, Sep 2, 2004
    #3
  4. "ma740988" <> wrote...
    > [....]
    > >
    > > If I were to nit-pick, I'd change
    > >
    > > memset(&midSection, ...
    > >
    > > to
    > >
    > > memset(&midSection[0][0], ...
    > >
    > > but it really shouldn't make any difference in the execution because the
    > > address of an array and the address of the first element of the array

    are
    > > the same (although their types are different).
    > >

    > Could you elaborate on the type differences here? I think I'm
    > following you but ....


    If 'a' is declared as

    T a[N];

    then its type is "array of N T". The expression '&a' then has the type
    "a pointer to an array of N T". The expression 'a[0]' has the type "T&",
    and '&a[0]' has the type "pointer to T", which is, incidentally, the type
    of the expression a. The name of an array decays to the pointer to the
    type of the element of the array.

    With a two- and more-dimensional arrays, the address where the array
    begins is the address of the first element, and if you need to iterate
    over those elements using a pointer arithmetic, it's better to use the
    pointer to an element than a pointer to the entire array. T* when
    incremented will point to the next element. T (*)[N] when incremented
    will point past the end of the array.

    For memset there is no need to worry because it operates in terms of
    bytes internally. But if you somehow encounter a function template,
    then correct types can be very important.

    Victor
     
    Victor Bazarov, Sep 4, 2004
    #4
  5. spoc

    Old Wolf Guest

    Victor Bazarov <> wrote:
    > spoc wrote:
    > > I am using VC++6 and Numega bounds checker and have been getting many STATIC
    > > MEMORY OVERRUN errors (boundschecker) while trying to track down bugs. An
    > > example is below:
    > >
    > > void func()
    > > {
    > > static int midSection[ 10 ][ 10 ];
    > > memset(&midSection, 0, sizeof(midSection));
    > > }

    >
    > If I were to nit-pick, I'd change
    >
    > memset(&midSection, ...
    > to
    > memset(&midSection[0][0], ...
    >


    Why? The first is fine, the second is technically UB (you are
    passing it a pointer to one int, and you overflow bounds by
    writing 100 ints to that pointer).
     
    Old Wolf, Sep 6, 2004
    #5
  6. "Old Wolf" <> wrote...
    > Victor Bazarov <> wrote:
    > > spoc wrote:
    > > > I am using VC++6 and Numega bounds checker and have been getting many

    STATIC
    > > > MEMORY OVERRUN errors (boundschecker) while trying to track down bugs.

    An
    > > > example is below:
    > > >
    > > > void func()
    > > > {
    > > > static int midSection[ 10 ][ 10 ];
    > > > memset(&midSection, 0, sizeof(midSection));
    > > > }

    > >
    > > If I were to nit-pick, I'd change
    > >
    > > memset(&midSection, ...
    > > to
    > > memset(&midSection[0][0], ...
    > >

    >
    > Why? The first is fine, the second is technically UB (you are
    > passing it a pointer to one int, and you overflow bounds by
    > writing 100 ints to that pointer).


    This is nonsense. Since there are 100 ints at that address, there
    is no overflow of any bounds and there is no UB.

    V
     
    Victor Bazarov, Sep 6, 2004
    #6
  7. spoc

    Old Wolf Guest

    "Victor Bazarov" <> wrote:
    > "Old Wolf" <> wrote...
    > > Victor Bazarov <> wrote:
    > > > spoc wrote:
    > > > > void func()
    > > > > {
    > > > > static int midSection[ 10 ][ 10 ];
    > > > > memset(&midSection, 0, sizeof(midSection));
    > > > > }
    > > >
    > > > If I were to nit-pick, I'd change
    > > > memset(&midSection, ...
    > > > to
    > > > memset(&midSection[0][0], ...

    > >
    > > Why? The first is fine, the second is technically UB (you are
    > > passing it a pointer to one int, and you overflow bounds by
    > > writing 100 ints to that pointer).

    >
    > This is nonsense. Since there are 100 ints at that address, there
    > is no overflow of any bounds and there is no UB.


    That doesn't answer the first question: why do you prefer
    midSection[0] (equivalent to &midSection[0][0]) to &midSection?
    For me, the least error-prone method of using the mem* functions
    is to pass the address of the object that is being set.
     
    Old Wolf, Sep 8, 2004
    #7
  8. Old Wolf wrote:
    > "Victor Bazarov" <> wrote:
    >
    >>"Old Wolf" <> wrote...
    >>
    >>>Victor Bazarov <> wrote:
    >>>
    >>>>spoc wrote:
    >>>>
    >>>>>void func()
    >>>>>{
    >>>>> static int midSection[ 10 ][ 10 ];
    >>>>> memset(&midSection, 0, sizeof(midSection));
    >>>>>}
    >>>>
    >>>>If I were to nit-pick, I'd change
    >>>> memset(&midSection, ...
    >>>>to
    >>>> memset(&midSection[0][0], ...
    >>>
    >>>Why? The first is fine, the second is technically UB (you are
    >>>passing it a pointer to one int, and you overflow bounds by
    >>>writing 100 ints to that pointer).

    >>
    >>This is nonsense. Since there are 100 ints at that address, there
    >>is no overflow of any bounds and there is no UB.

    >
    >
    > That doesn't answer the first question: why do you prefer
    > midSection[0] (equivalent to &midSection[0][0]) to &midSection?
    > For me, the least error-prone method of using the mem* functions
    > is to pass the address of the object that is being set.


    I prefer using &midSection[0][0] because it has the correct type --
    a pointer to int. Not a pointer to an array of 10 arrays of 10 ints,
    not a pointer to an array of 10 ints.

    See my reply to the OP earlier in this thread.

    Victor
     
    Victor Bazarov, Sep 8, 2004
    #8
  9. spoc

    Old Wolf Guest

    Victor Bazarov <> wrote:
    > >>"Old Wolf" <> wrote...
    > >>>Victor Bazarov <> wrote:
    > >>>>spoc wrote:
    > >>>>
    > >>>>> void func()
    > >>>>> {
    > >>>>> static int midSection[ 10 ][ 10 ];
    > >>>>> memset(&midSection, 0, sizeof(midSection));
    > >>>>> }
    > >>>>
    > >>>>If I were to nit-pick, I'd change
    > >>>> memset(&midSection, ...
    > >>>>to
    > >>>> memset(&midSection[0][0], ...
    > >>>
    > >>>Why?

    > I prefer using &midSection[0][0] because it has the correct type --
    > a pointer to int. Not a pointer to an array of 10 arrays of 10 ints,
    > not a pointer to an array of 10 ints.
    >
    > See my reply to the OP earlier in this thread.


    "pointer to int" isn't the correct type. You aren't filling a
    block of ints with int 0. You are filling an object with char 0.
    memset fills byte by byte (even though the memset function takes
    a parameter of type int for the fill char, it converts it to a
    char in order to fill).

    You mentioned needing correct types for template functions: the
    equivalent of memset is std::fill_n<charT *, size_t, charT>().
    If you call std::fill_n(ptr, 100, '\0') then ptr should be a
    pointer to char (not a pointer to int).

    I interpret memset as "fill an object (given a pointer to it
    and its size). So passing a pointer to the object (ie. &midSection)
    is correct.

    This is of course all moot, as memset takes a (void *) and the
    standard practically guarantees that (void *)&midSection ==
    (void *)&midSection[0][0].
     
    Old Wolf, Sep 9, 2004
    #9
    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. J. Campbell
    Replies:
    7
    Views:
    393
    Old Wolf
    Aug 17, 2004
  2. Anthony Baxter
    Replies:
    0
    Views:
    272
    Anthony Baxter
    Oct 12, 2006
  3. Martin Eisenberg

    Buffer overrun - exit or abort?

    Martin Eisenberg, Jan 16, 2006, in forum: C++
    Replies:
    8
    Views:
    451
    Earl Purple
    Jan 18, 2006
  4. Nico
    Replies:
    2
    Views:
    307
    Salt_Peter
    Oct 15, 2006
  5. =?Utf-8?B?TGl0dGxlbXV6?=

    buffer overrun

    =?Utf-8?B?TGl0dGxlbXV6?=, Aug 27, 2007, in forum: ASP .Net
    Replies:
    3
    Views:
    1,892
    =?Utf-8?B?SXBvZHVzZXI=?=
    Nov 11, 2007
Loading...

Share This Page