Dynamic Memory Allocation - Reallocating Multiple Times
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?
Do you need subscript access? If so, use std::vector, if not, use std::list. Otherwise, look into placement new
Actually, on second thoughts, don't 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:
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'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:
Remove a character:
Hope that helps.
(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
Popular Topics
Advertisement