Thread: Reducing the size of a dynamically allocated array?

  1. #1
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171

    Question 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. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    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().
    Last edited by GReaper; 11-09-2018 at 06:12 AM.
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    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. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    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.
    Last edited by laserlight; 11-09-2018 at 07:16 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    • 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();

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote 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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. size of dynamically allocated block of memory
    By monkey_c_monkey in forum C++ Programming
    Replies: 12
    Last Post: 07-10-2012, 05:05 AM
  2. Replies: 8
    Last Post: 02-29-2012, 02:25 PM
  3. Dynamically Allocated Array
    By chris4 in forum C Programming
    Replies: 9
    Last Post: 05-06-2011, 10:01 AM
  4. Dynamically allocated array
    By dre in forum C Programming
    Replies: 17
    Last Post: 08-13-2009, 06:57 PM
  5. Dynamically allocated size
    By maverickbu in forum C++ Programming
    Replies: 12
    Last Post: 06-26-2007, 01:16 PM

Tags for this Thread