Dynamic Memory Allocation - Reallocating Multiple Times

Started by
7 comments, last by kdogg 19 years, 7 months ago
Before I go out there and do something stupid, is it possible to reallocate more memory for a variable and keep what's in it so far? I have an int array (pointer), and I'll need to constantly allocate more and more memory for it. I need to keep what's in it so far every time, however. Also, how can I slim down the size of it without losing all of it? Example: int* array = new int[ SomeInt ]; //later on... array = new int[ SomeInt+1 ]; // would previous contents still be intact? // later on... array = new int[ SomeInt ]; // Is this how you 'slim it down'? Would everything not slimmed down be intact?
.:<<-v0d[KA]->>:.
Advertisement
Do you need subscript access? If so, use std::vector, if not, use std::list. Otherwise, look into placement new

int * ptr = new int[3];int * ptr_a = new (ptr + 3) int(4);ptr[0] = 1;ptr[1] = 2;ptr[2] = 3;int * ptr_b = new (ptr) int[4];cout << ptr_b[0] << " " << ptr_b[1] << " " << ptr_b[2] << " " << ptr_b[3] << endl;


Actually, on second thoughts, don't look into placement new.
To answer the original question ;), that wouldn't work - each subsequent 'new' allocates an entirely new and unrelated block of memory somewhere and changes the pointer to point to it.

As the above poster mentioned though, std::vector really is the way to go if you want resizable arrays. Example:

#include <vector>using namespace std;void main(){  vector<int> foo; // a vector for storing objects of type int  foo.clear();     // always clear your STL containers!  int a = 5;  foo.push_back(a); // add 5 to the vector                    // ... and so on, just keep adding them, no need to allocate memory or do any tricky resizing yourself  // when you want to access it, there's a few ways to do it  // the most flexible is to use iterators:  for (vector<int>::iterator i = foo.begin();       i != foo.end(); i++)    cout << *i; // each iteration of i is a pointer to an element of the vector  // fastest way:  int* b = &foo[0];  for (int i = 0; i < foo.size(); i++)    cout << b;}

---PS3dev
Quote:By davedx : from Brisbane

Good luck in the league this week, sucker.
Broncos PWN you all! :D
(I'm actually a pommie, but yeah...)
---PS3dev
I'm a cowboy fan, obviously, and it'll be great to get to watch the semi in Townsville *hopefully*.
Quote:Original post by Chris Hare
Do you need subscript access? If so, use std::vector, if not, use std::list. Otherwise, look into placement new

*** Source Snippet Removed ***

Actually, on second thoughts, don't look into placement new.


Exactly; when you do the placement new, you're not at all guaranteed that you have as much memory available in that one place as you need.

To the OP, this is indeed *exactly* what std::vector is for. It provides a method (.trim() I think?) to reduce the allocated size later on, if you really need to do so. Chances are you shouldn't worry about it. The vector will also keep track of how much of the allocated size is actually *used* (and in the general case, there will be unused space).
If you want to handle dynamically de/allocating memory by yourself then you will simply just need to do the following:

(1)Take the size of your original array.
(2)Create a new array the same size as your original and transfer all information to this new one.
(3)Resize the original array to the size you want it to be - larger or smaller.
(4)Transfer the contents of your new array into your original, newly updated dimensions, array.

Here are two samples that are from my opengl console emulator.

Add a character:
                   //Convert loop contents to character then place in string buffer                    unsigned int ascii_value=MapVirtualKeyEx(loop, 2, CL_System.keyboard);                    char buffer[2];                    sprintf(buffer, "%c", (char)ascii_value);                    //Add the character to the user string                    strcpy(CL_UserString.hold, CL_UserString.user); //Copy to temp location                    delete [] CL_UserString.user; //Delete source character array                    CL_UserString.user=new char [strlen(CL_UserString.hold)+2]; //Allocate new size "+1 entry" and plus 1 for null terminator                    strcpy(CL_UserString.user, CL_UserString.hold); //Copy temp location's contents to source character array                    delete [] CL_UserString.hold; //Delete temp character array                    CL_UserString.hold=new char [strlen(CL_UserString.user)+2]; //Allocate new size for use next time                    if(GetAsyncKeyState(VK_SHIFT)) //Determine if shift key is pressed                    {                         buffer[0]=toupper(buffer[0]);                    }                    else                    {                         buffer[0]=tolower(buffer[0]);                    }                            strcat(CL_UserString.user, buffer); //Attach new character to user string contents                    CL_UserString.x_change=TRUE; //Toggle to invalidate string length


Remove a character:
                    //Delete the last character to the user string                    strcpy(CL_UserString.hold, CL_UserString.user);                    delete [] CL_UserString.user;                    CL_UserString.user=new char [strlen(CL_UserString.hold)-1];                    for(int loop=0; loop < strlen(CL_UserString.hold)-1; loop++)                    {                        CL_UserString.user[loop]=CL_UserString.hold[loop];                    }                        CL_UserString.user[strlen(CL_UserString.hold)-1] = 0; //Null terminator                    strcpy(CL_UserString.hold, "");                    CL_UserString.x_change=TRUE;


Hope that helps.
Basically, resizing an array is not a cheap operation. The only way to do it is how Xiachunyi just said. If you need to resize your array very frequently, you might be better off using a linked list, since it's generally a cheaper operation to resize lists than arrays.

This topic is closed to new replies.

Advertisement