Thread: Reducing the size of a dynamically allocated array?

1. Reducing the size of a dynamically allocated array?

Hi! So we are trying to learn about pointers and dynamic memory allocation, but the problem is that we get "garbage values" because when we try to allocate a smaller array that is half the size of the original array, we can no longer print out 10 elements in it since it can only store 5 for example (Assuming input was 10).

The rest of the values indexes do not exist right? So that is why we get "garbage values". We can have misinterpreted the question they asked but we thought that they wanted us to print all 10 elements that the array was filled up with from the beginning, or do they want us to just print 5 elements since we have reduced the array?

Assignment instruction:
"In this exercise, create a small program which starts by asking theuser for a positive integer larger than zero. Dynamically allocate aninteger array with a size that corresponds to the inputted integer, andfill it with numbers from 0- (input - 1). Now create a loop that printsthe integers in backwards order. Once a point is reached in the loopat which half of the current array has been printed, allocate a newarray that can fit the remaining integers, copy the non-printed integersover from the old larger array into the new smaller array, delete theold array, and set the pointer to point at the new array. Continue thisprocess until all values have been printed. Do not forget to delete thearray when you are done with it."

Code:
```
Code:
void DisplayArray(std::string msg, int arr[], const int size) {
std::cout << msg << std::endl;
for (int i = size - 1; i >= 0; i--) {
std::cout << arr[i] << std::endl;
}
}

int main()
{
int *currentArr;
int input;
std::cout << "Enter the size (larger than 0) of the array: \n";
std::cin >> input;
getchar();
currentArr = new int[input];
for (int i = 0; i < input; i++)
{
currentArr[i] = i;
std::cout << currentArr[i] << '\n';
}

for (int i = (input-1); i > 0; i--)
{
if (i >= input / 2)
{
std::cout << "\nInside first if: ";
std::cout << currentArr[i] << '\n';
}
else if (i < input / 2)
{
// This will shrink until 1 place left if using "i" to allocate the array
const int halfSize = input / 2;
int *halfArr = new int[halfSize];

// Remember that we put all values in half array of original array
for (int j = 0; j < halfSize; j++)
{
halfArr[j] = currentArr[j];
}
std::cout << "\nElse if before del: " << halfArr[i];

delete[] currentArr;
currentArr = nullptr;

currentArr = halfArr;
std::cout << "\nElse if: " << currentArr[i];
}
}

DisplayArray("\n\nStored array", currentArr, input);

getchar();
}
```

2. You pass the original size as input to DisplayArray(), but that is no longer the size of currentArr. You should either change the value of "input" to the new size or use a new variable.

Also, since you're using C++ and not C, prefer std::cin.get() or std::cin.ignore() over getchar().

3. So like this then:

Code:
```void DisplayArray(std::string msg, int arr[], const int size) {
std::cout << msg << std::endl;
for (int i = size - 1; i >= 0; i--) {
std::cout << arr[i] << std::endl;
}
}

int main()
{
int *currentArr;
int input;
int halfSize = 0;
std::cout << "Enter the size (larger than 0) of the array: \n";
std::cin >> input;
std::cin.ignore();
currentArr = new int[input];
for (int i = 0; i < input; i++)
{
currentArr[i] = i;
std::cout << currentArr[i] << '\n';
}

for (int i = (input-1); i > 0; i--)
{
if (i >= input / 2)
{
std::cout << "\nInside first if: ";
std::cout << currentArr[i] << '\n';
}
else if (i < input / 2)
{
// This will shrink until 1 place left if using "i" to allocate the array
halfSize = input / 2;
int *halfArr = new int[halfSize];

// Remember that we put all values in half array of original array
for (int j = 0; j < halfSize; j++)
{
halfArr[j] = currentArr[j];
}
std::cout << "\nElse if before del: " << halfArr[i];

delete[] currentArr;
currentArr = nullptr;

currentArr = halfArr;
std::cout << "\nElse if: " << currentArr[i];
}
}

DisplayArray("\n\nStored array", currentArr, halfSize);

std::cin.ignore();
}```
And I'll start using std::cin.get() and std::cin.ignore() from now

4. My comments:
• Looking at your instructions, you don't need DisplayArray in the first place. You're supposed to print the second half of the dynamic array from the end each time and then copy the unprinted first half to another dynamic array, which means that by the end, you have a dynamic array of just one element that was already printed on the last iteration of the loop.
• input is too generic a name; size or following your abbreviation arrSize would be more descriptive.
• Declare variables near first use; in particular, it is best to declare them at the point where you can give them a meaningful initial value. So, instead of declaring currentArr and later assigning to it, just write:
Code:
`int* currentArr = new int[input];`
Likewise, halfSize was better declared as in your post #1 rather than your post #3.
• You need to update size with halfSize. I'm deliberately calling it size now because it is harder to reason about that when you call it input. Calling it size means you know it is the size of currentArr, and if you keep halving currentArr, clearly you need to keep halving size.
• There is no need to first assign nullptr to a pointer when you're immediately going to assign another pointer to it.
• Despite the reminder in your instructions, you forgot to delete[] currentArr when done with it.

• Looking at your instructions, you don't need DisplayArray in the first place. You're supposed to print the second half of the dynamic array from the end each time and then copy the unprinted first half to another dynamic array, which means that by the end, you have a dynamic array of just one element that was already printed on the last iteration of the loop.

So you mean that I just have to print the elements of currentArr somewhere
in my for loop to get this correct. I thought I was supposed to print the array
"outside" of the for loop. In another for loop.

And yes, I know that this isn't the code to do that yet. I'm working on it.
Code:
```    int arrSize;
std::cout << "Enter the size (larger than 0) of the array: \n";
std::cin >> arrSize;
std::cin.ignore();
int* currentArr = new int[arrSize];
for (int i = 0; i < arrSize; i++)
{
currentArr[i] = i;
std::cout << currentArr[i] << '\n';
}

for (int i = (arrSize-1); i > 0; i--)
{
if (i >= arrSize / 2)
{
std::cout << currentArr[i] << '\n';
}
else if (i < arrSize / 2)
{
const int halfSize = arrSize / 2;
int *halfArr = new int[halfSize];

for (int j = 0; j < halfSize; j++)
{
halfArr[j] = currentArr[j];
}

delete[] currentArr;
currentArr = nullptr;

currentArr = halfArr;
}
}

delete[] currentArr;

std::cin.ignore();```

5. Originally Posted by DecoratorFawn82
So you mean that I just have to print the elements of currentArr somewhere
in my for loop to get this correct. I thought I was supposed to print the array
"outside" of the for loop. In another for loop.
Create a small program which starts by asking the user for a positive integer larger than zero. Dynamically allocate an integer array with a size that corresponds to the inputted integer, and fill it with numbers from 0- (input - 1). Now create a loop that prints the integers in backwards order. Once a point is reached in the loop at which half of the current array has been printed, allocate a new array that can fit the remaining integers, copy the non-printed integers over from the old larger array into the new smaller array, delete the old array, and set the pointer to point at the new array. Continue this process until all values have been printed. Do not forget to delete the array when you are done with it.

So no, I don't mean that you "just have to print the elements of currentArr somewhere in my for loop to get this correct". It is right there in the instructions that you posted. It has nothing to do with me.

Popular pages Recent additions