Thread: how to double an array size?

  1. #16
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by laserlight View Post
    That's nonsense. This "requirement" is derived from the requirement of aligned storage, but "new char[sizeof(Foo)]" is no more guaranteed to be suitably aligned for Foo than "char buffer[sizeof(Foo)]". By the letter of the standard, anyway. However, operator new is required to return storage aligned for any type, so in practice this is a non-issue for new.

    For the stack, you have to align the memory. You do that either by over-allocating and adjusting the address:
    Code:
    char buffer[sizeof(Foo) + alignof(Foo) - 1];
    new ((buffer + alignof(Foo) - 1) % alignof(Foo)) Foo;
    Or by making sure the alignment is right in the first place.
    Code:
    typedef ... type_with_foo_alignment;
    union { type_with_foo_alignment aligner; char mem[sizeof(Foo)]; } buffer;
    new (buffer.mem) Foo;
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #17
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    this has worked well for me so far.

    Code:
    template <class T> T* arrayResize(T *arr,const unsigned int oldSize,const unsigned int newSize, T defaultVal)
    {
            arr = (T *)realloc(arr,sizeof(T)*newSize);
            if(newSize>oldSize)
            {
                    for(unsigned int i=oldSize;i<newSize;i++)
                    {
                            arr[i]=defaultVal;
                    }
            }
            return arr;
    }

  3. #18
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    this has worked well for me so far.
    I suggest that you read Stroustrup's answer to the FAQ: Why doesn't C++ have an equivalent to realloc()?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #19
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by laserlight View Post
    I suggest that you read Stroustrup's answer to the FAQ: Why doesn't C++ have an equivalent to realloc()?
    excellent to know! i was sure if i posted this someone would elucidate the potential pitfalls with some bit of arcane trivia

    this makes sense though; realloc couldn't possibly invoke a copy constructor. it has no information about the objects in use.

    i don't have any user defined copy constructors, so that explains why it's worked for me so well.

    would the following be safe for classes containing copy constructors?

    Code:
    template <class T> T* arrayResize(T *arr,const unsigned int oldSize,const unsigned int newSize, T defaultVal)
    {
            T *tempArr = new T[oldSize];
            for(int i=0;i<oldSize;i++)
            {
                    tempArr[i]=arr[i];
            }   
            arr = (T *)realloc(arr,sizeof(T)*newSize);
            unsigned int size;
            if(oldSize>newSize)
            {
                    size = newSize;
            }
            for(int i=0;i<size;i++)
            {
                    arr[i]=tempArr[i];
            }
            if(newSize>oldSize)
            {
    
                    for(unsigned int i=oldSize;i<newSize;i++)
                    {
                            arr[i]=defaultVal;
                    }
            }
            delete tempArr;
            return arr;
    }

  5. #20
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I am not sure what are the effects of using realloc() with new[] even when you take pains to copy back, so I shall not comment on that.

    However, I note that you did not match the new[] with delete[] (but with delete, which is incorrect), and that if the new size is less than the old size, you might as well return immediately. The realloc() does not seem useful in the first place: if you have a pointer to a temporary array, you might as well create that array with the new size, and then copy over the elements, then assign the pointer to the original (or in this case, return the pointer to the "temporary" array). At the moment you are copying back and forth, which is a waste of time.

    You might want to read the "Allocating Arrays Using Placement new" article, especially the "Performance Tuning" section. Also, note that this is dotz02x's thread, so perhaps you would like to give dotz02x a chance to post an attempted solution.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #21
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    sorry. is this a homework assignment or something? i can't tell.

    i'm posting because i've recently confronted the issue myself and i suspected, as you've confirmed, i was doing it wrong.

    anyway, your other points are well taken. i'll stfu now i guess.
    Last edited by m37h0d; 04-25-2008 at 08:56 AM.

  7. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I am not sure what are the effects of using realloc() with new[]
    It's undefined. Always.

    arr = (T *)realloc(arr,sizeof(T)*newSize);
    Note that the pattern p = realloc(p, size); is always, without exception, wrong.

    The pattern must always be
    Code:
    T *tmp = realloc(p, size);
    if(tmp == 0) {
      // error out
      return 1;
    }
    p = tmp;
    That's because if realloc cannot find enough memory, it returns null and leaves the original block untouched. If you do p = realloc(p, size) in such a case, you'll overwrite the pointer to the old block with null. So not only did you not get a new block, you also lost the pointer to the old block (which then leaks).

    Since in most programs and most parts of most programs, out-of-memory is not a recoverable situation, you can use something like this, though:
    Code:
    void *realloc_a(void *in, size_t newsize)
    {
      void *t = realloc(in, newsize);
      if(!t) {
        fprintf(stderr, "Failed to reallocate &#37;d bytes of memory.\n", newsize);
        abort();
      }
      return t;
    }
    Now you may do
    Code:
    p = realloc_a(p, size);
    because realloc_a never returns null.



    This is all only relevant to C, though. In C++, use a std::vector.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #23
    Registered User
    Join Date
    Apr 2008
    Posts
    20
    Well, thanks for all the feedback but i found my own way to attack this problem and it was by creating a temporary array that is doubled the size, copying the old array to new then deallocating the old and then dynamically allocating the new array again at a larger size and copy the new array to the old array. Then deallocating the new array.

  9. #24
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Err, well, that is to say, store your array in a temporary one, delete the old array, and then reassign a larger array. When you finish copying from the temporary to the new array, delete the temporary.

  10. #25
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Well, thanks for all the feedback but i found my own way to attack this problem and it was by creating a temporary array that is doubled the size, copying the old array to new then deallocating the old and then dynamically allocating the new array again at a larger size and copy the new array to the old array. Then deallocating the new array.
    That is a possible solution

    However, it would be even simpler to:
    1. Create a new array twice the size.
    2. Copy the old array to the new array.
    3. Deallocate the old array.
    4. Point the old array to the new array.

    I do not think it is necessary to copy back and forth, as in citizen's suggestion, because you can assign pointers.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #26
    Registered User
    Join Date
    Apr 2008
    Posts
    20
    thats what i mean lasterlight hehe my mistake on my wording

  12. #27
    Registered User
    Join Date
    Apr 2008
    Posts
    20
    but i have one question how do i access a private function declared in a class within a class?
    For example:
    Code:
    class Test 
    {
    private:
    int size;
    string * sent;
    void extend() const;
    public:
    void check() const;
    };
    lets just say my constructors and stuff are all created and i wish to access extend() in the function check(). How would i go about getting this?

  13. #28
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by dotz02x View Post
    but i have one question how do i access a private function declared in a class within a class?
    For example:
    Code:
    class Test 
    {
    private:
    int size;
    string * sent;
    void extend() const;
    public:
    void check() const;
    };
    lets just say my constructors and stuff are all created and i wish to access extend() in the function check(). How would i go about getting this?
    You would type "extend()".

  14. #29
    Registered User
    Join Date
    Apr 2008
    Posts
    20
    well i have another problem now i get a double free error when i try to extend it more than once

  15. #30
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Then you have a problem with your free. I've seen the four-step process posted above; my guess is you didn't implement step 4 correctly.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Testing some code, lots of errors...
    By Sparrowhawk in forum C Programming
    Replies: 48
    Last Post: 12-15-2008, 04:09 AM
  2. Replies: 16
    Last Post: 11-23-2007, 01:48 PM
  3. need some help with last part of arrays
    By Lince in forum C Programming
    Replies: 3
    Last Post: 11-18-2006, 09:13 AM
  4. Unknown Math Issues.
    By Sir Andus in forum C++ Programming
    Replies: 1
    Last Post: 03-06-2006, 06:54 PM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM