Dynamic array seems bigger than the dynamic size variable for it - c++

I have class A, in it I have a dynamic array arr and a dynamic variable s which determines the size of the array. At the start of my main I use the constructor for class A which sets s to 2 and fills the arr with dummy objects. Now when I add objects to the array and sort it, objects seem to disappear.
The size of my array (so variable s) gets doubled when there is not enough space in the array, so no free slot available.
The way I display the array is by using a for loop with the limit i < s. So it should display all objects in the array.
Now when I add more objects and the array gets bigger, the previously "lost" objects start to appear again. So it seems like my array is bigger than the variable s, which dynamically determines the size.
How is that possible?
class A
private:
int *s = new int;
obj *arr = new obj[*s];
//triggers when trying to add an object to the array, but every place from
//arr[0] to arr[s-1] is taken by non dummy object
void A::resize {
*s *= 2;
//for loop that fills code with dummy objects
}
void A::display {
for (int i = 0; i < *s; i++) {
displayobject(i);
}
}
I had a very similar code last year in university and everything worked fine, can't find my mistake.
I would just use a vector, where i can easily use a for loop to go through the real size, but our prof wants us to use a dynamically alocated array.

Related

Passing array values from a function back into a struct

I am currently working on a program that requires a function to figure out array values and then stores those values in arr1[], which has an unknown size and is calculated within the function. It then passes back the entire array along with the size of the array back to the main function. Using a struct, I returned the size, but I cannot return the array for some reason. Can someone please direct me in the right direction with what I'm doing wrong?
Here is my struct:
struct Arr
{
int size_1;
int arr_1[];
};
And here is part of my function that returns the array, where arr1[] is the array in which I need to return:
Arr smallElement(int arr[], int size)
{
Arr tempArr;
for (int count = 0; count < newSize; count++)
{
tempArr.arr_1[count] = arr1[count];
}
return tempArr;
}
This is what I use in my main function to call the function to print the array, but it just prints 3 random numbers every time:
Arr a;
a = smallElement(array, n);
cout << "The array is: ";
for (int count = 0; count < a.size_1; count++)
{
cout << a.arr_1[count] << " ";
}
Inside a struct, int arr_1[] does not define an actual array. It is actually just a placeholder called a flexible array member. In C, this is used by allocating memory for the fully defined part of the struct plus additional space for the array—you have to manually add space when using malloc or other memory allocation. In standard C++, you should not use this. (It is not part of standard C++. It is an extension adopted by some compilers from C, where it is standard.)
When you declared tempArr, it created just the fully defined portion of the struct. When you assigned values to tempArr.arr_1[count], there was no allocated array there, so the behavior is undefined. When you return tempArr, a copy of the struct is returned, but, again, only a copy of the defined portion.
If the caller knows the size the array will be, you may want to have them pass the array to the function, perhaps by allocating it with new or by using std::vector and passing the vector by reference. If the size is not known by the caller, then you may want to have the function allocate the array and return a pointer to it (in which case the caller is responsible for deleting it later), or you may want to pass an empty (or otherwise available for re-use) std::vector to the function, preferably by reference. Inside the function, it can add more elements to the vector, and the std::vector will manage memory allocation for you.

Copy array then delete original

I have an array of a structure (with the parameters of name and number), and the initial array takes in elements from a document that I've made. The initial list size starts at 1000. When the list fills up, I call another method that I'm struggling with. I would like for it to copy the data into a new array that doubled the size, and then delete the old array.
If I name it: array1 and array2, I have my program use array1 throughout. I need help with the pointers that would get array2 to work as array1.
Is there a way to copy the array to a temp array of the same or new size, and then remake the initial array reassigning back to that? For this exercise, I can't use vectors. While I know how to use them, and that they solve this issue while being better, I'm trying to do it with only arrays.
using namespace std;
struct Information {
char functionality;
int SSN;
string name;
};
int numPeople = 1000;
//Gets called if the initial array (whatever size) is filled
void doubleArray(Information *array){
numPeople = numPeople * 2;
//Will now be the doubled array size
Information temp[numPeople]
for(int i = 0; i < numArray; i++){
temp[i].SSN = array[i].SSN;
temp[i].name = array[i].name;
}
//Normally makes it crash
delete[] array;
}
edit: This is what I currently have
void doubleArray(Information *person){
numPeople = numPeople * 2;
Information* temp = new Information[numPeople];
memcpy(temp, person, numPeople);
delete[] person;
person = temp;
}
It gets to numPeople = 1000 (the initial list size) but then crashes shortly after. Is the doubling array correct?
Arrays are fixed size. You cannot change the capacity of the original array.
{Use std::vector}
You can have a pointer to an array. And use the same pointer. When the array is full, you can allocate another array, copy old array items to new array, delete the old array and assign your array pointer to the new array.
{Did I mention std::vector?}
By the way, there is a data structure that performs resizing as necessary. If I recall correctly, it is std::vector. Try it out. :-)
Assuming you are using std::array (which you should be), then copying the array is very easy.
std::array<myStruct, 1000> array1{};
std::array<myStruct, 2000> array2{};
// codes...
std::copy(array1.begin(), array1.end(), array2.begin())
However, this is a specific scenario in which you only use these two arrays. It will not dynamically double the size of the array as you simply cannot do this dynamically with stack-based arrays, just like c arrays[].
What you can, and should, be using is std::vector<myStruct>. This will dynamically grow as you need it. Until you provide us with code and a more specific issue, this is the best advice that I can offer with the information provided.
If you aren't allowed to use std::vector, as one of your comments stated, then you'll want to look at dynamic allocation.
size_t sz = [whatever];
// Dynamically allocate an array of size sz.
T* T_array = new T[sz];
// Do whatever...
delete[] T_array; // new[] needs to be paired with delete[].
T_array = nullptr; // Not strictly necessary, but a good idea if you have more code after.
As the size doesn't need to be constant for a dynamic array, this will allow you to allocate memory as necessary. You can then use std::copy() to copy data from one array to the other, as Goodies mentioned.
[For more information on dynamic allocation, see here.]

C++ How to create a dynamic array of vectors?

I'm having problem initialising an array of std::vectors.
I'm declaring and initialising it like this:
vector<component_change*>* _changes;
_changes = new vector<component_change*> [numThreads];
in the hope that it's in the same form as this:
int * foo;
foo = new int [5];
but when I hit a breakpoint after the initialisation, _changes' size is 0.
What am I doing wrong and how can I fix it?
I don't want to use a vector of vectors as the number I need remains constant throughout the program but depends on the current hardware. And I'm not just looking for a single vector (Each vector will be used by a different thread then merged when the threads have finished their tasks).
Thanks guys! :)
Your program is correct. But you misinterpreted the debugger. _changes's size is not 0, but the first vector in your array (the one _changes points at) is empty. Thats because the debugger does not know if _changes points at a single element or an array (in that case the compiler would not know how many elements are in that array). Simply use a vector and call std::vector::shrink_to_fit.
If the size can be determined at compile time use a std::array. If the size is a run-time argument then use a vector and don't change the size of the container.
Are you interested in have a vector for each thread, or a vector containing items used by each thread? I assumed the later, but my answer could be adapted.
This is using a statically sized array; (this syntax is close).
const int NUMBER_OF_THREADS = 5;
component_change* _changes[NUMBER_OF_THREADS] =
{
new component_change(1),
new component_change(2),
new component_change(3),
new component_change(4),
new component_change(5)
}
If the number of threads is dynamic, you will have to use a new...
int NUMBER_OF_THREADS = system.getThreadCount();
component_change* _changes = new component_change[NUMBER_OF_THREADS];
for (int i = 0; i < NUMBER_OF_THREADS; i++)
{
_changes[i] = new component_change(i+1);
}
If you want to a std::vector:
int NUMBER_OF_THREADS = system.getThreadCount();
std::vector<component_change*> _changes;
_changes.reserve(NUMBER_OF_THREADS);
for (int i = 0; i < NUMBER_OF_THREADS; i++)
{
_changes.push_back(new component_change(i+1));
}
I think you're kind of mislead, this size that you are reading belongs to the vector in the first element of the array. Its size is equal to 0 since no elements have been inserted in the vector yet.
new vector is usually wrong.
You should use, with most preferred if possible first,
std::vector<component_change> _changes(numThreads);
or
std::vector<std::unique_ptr<component_change>> _changes(numThreads);
or
std::vector<component_change*> _changes(numThreads);
or if each element of the vector should itself contain an array of components (it's not clear in your question)
std::vector<std::vector<**component_change**>> _changes(numThreads);
Declaring the component as one of the above ways, depending on your needs.
Note that the pointers begin not pointing to anything. You'd have to allocate the individual components as a separate step.
The following creates an array of numThreads vectors, not a vector of numThread elements.
new vector<component_change*> [numThreads]

Create dynamic array based on an array returned by a function

I'm currently trying to learn C++, and one of the training exercises I'm doing asks that I do the following:
Create a dynamic array, add 100 int values to it.
Write a function that calculates the square of each array element, and save this int value as position 100 + element_index in the array.
At the current moment I have created a dynamic array and filled it with pseudo-random values. What I want to do is to calculate the square of these random values, and "append" them at the end of the array.
The variable firstArray is defined earlier, but is set to be 100.
typedef int* intPtr;
...
...
srand((unsigned)time(0));
intPtr myArray;
myArray = new int[firstArray];
for (int i = 0; i < firstArray; i++)
ptr[i] = (rand() % 10);
This creates my initial dynamic array, and gives each location in the array a random value between 0 and 10.
If I don't have to use a function, I can easily create a new dynamic array, copy the first 100 values in, and then calculate the squares and place them at the end. I have an attempt at some pseudo-code for the exercise, but I'm unsure as how to properly implement it.
Create dynamic array of size 100, called myArray
Fill each indexed location with a random value between 0 and 10
Pass the dynamic array into a function
Function creates a new dynamic array of size 200
The values on location 0-99 from myArray are copied over
Calculate the square of the value on location n, and write it to location n+100
Return the dynamic array
Delete [] myArray
Create new dynamic array of size 200, called myArray
Copy the values from the array returned by my function into myArray
Delete the array returned from my function
My question relates to passing the information into a function, and returning the new information:
How do I create a function that I can pass a dynamic array into, and have it return another dynamic array?
If it is not possible to have this question answered, I would also very much like feedback on structure, information included in the question and if this is not the right type of question to ask, so I can ask better questions in the future.
Function that takes a dynamic array and returns a dynamic array (of ints) would have this signature:
int* newArray(int* array, int size);
An implementation would then start with:
int* newArray(int* array, int size)
{
int* ret = new int[size * 2]; // double the size
// stuff to populate ret
return ret;
}
int* myBiggerArray = newArray(myArray, firstArray);
// use myBiggerArray
delete [] myBiggerArray;
Also, stay away from typedefing things like int*. int* is already clear and concise enough.
I don't see any requirement that the array needs to be allocated twice. You can allocate all the memory once.
// Allocate all the memory.
intPtr myArray = new int[firstArray*2];
// Fill the first part with random numbers
for (int i = 0; i < firstArray; i++)
ptr[i] = (rand() % 10);

How to remove elements from dynamically allocated array?

I have a dynamically allocated array :
myRectangle lastRectanglesArray = new myRectangle[lastMaxLabel];
I would like to loop through all elements in this array and remove these that will meet my condition (e.g. too big rectangle).
I have been thinking that I can loop through this array and get the number of elements that would satisfy my condition and then allocate a new array. But how can I 'transfer' these 'wanted' elements into my new array ?
Just for the record: I cannot use STL containers.
myRectangle * lastRectanglesArray = new myRectangle[lastMaxLabel];
// initialize the entries in the lastRectanglesArray
// create a temporary array which contains info about each individual
// entry. namely, it only holds info about whether the entry should
// be kept, or deleted.
// we also use the 'entries' value, which is the number of entries
// in the new array
bool * entriesToKeep = new bool[lastMaxLabel];
int entries = 0;
// check each entry, and mark whether it should be kept or deleted
for (int i = 0; i != lastMaxLabel; ++i) {
// check whether the entry should be kept or deleted...
// here, i just put a function with signature like:
// bool shouldKeepRectangle(const myRectangle &);
entriesToKeep[i] = shouldKeepRectangle(lastRectanglesArray[i]);
if (entriesToKeep[i]) ++entries;
}
// create a new array that will contain the entries that should be kept
myRectangle * rectanglesArray = new myRectangle[entries];
// assign the entries in the new array
for (int i = 0, j = 0; i != lastMaxLabel && j != entries; ++i) {
if (entriesToKeep[i])
rectanglesArray[j++] = lastRectanglesArray[i];
}
// free the memory held by the temp array
delete [] entriesToKeep;
// if the old array is not needed anymore, delete it
delete [] lastRectanglesArray;
// and here you have rectanglesArray, a brand new array that contains
// only the elements that you need.
Just move the next array location over the one that needs to be deleted, and shift everything over til the end of the array.
Yours look like the perfect case for using a Linked List. You would however have to do away with the new myRectangle[lastMaxLabel] part as you would have to implement it as pert of your Insert() function.
This way you would not require to transfer the wanted elements into a new array, but just delete the unwanted element.
Any more light on your use-case would help us to think of better alternatives.
I agree with Michael Chinen - use std::vector instead. You'll avoid lots of other potential problems this way. If you really want to use dynamic arrays, see this question: Remove an array element and shift the remaining ones
if you have a big amount of data in array that will be a problem for shifting using loop
maybe you should build your own array management class (find,add,deleteAt,etc).
my suggestion use link list node method.. it will be faster rather then you use loop for shifting.