Sign in to follow this  

Dynamic Memory Allocation - Reallocating Multiple Times

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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[i];
}


Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this