2

This code is for a CS 235 class, but I'm new to C++ and I have no clue how they want me to do this. The grow function works by taking in an array and changing it to become twice as large. Coming from python, I guess this is the equivalent of mutating the array? Anyway, I can't get it do the same for the insert function. I need it to check if the position that we're trying to insert an item at is outside the array bounds and make the array big enough that it can insert the value. Everything works....inside the function. The array does not maintain the changes outside the function. I've tried passing it in as a pointer, as a (reference to a pointer?) like *&array, and basically any combination I can think of.

void grow(int *&original_array, unsigned int & capacity){
    int *temp = new int[capacity * 2];
    for (int i=0; i<capacity*2; i++){
        temp[i] = 0;
    }
    std::cout << "line 18: ";
    print_array(temp, capacity*2);
    for(int i=0; i<capacity; i++){
        temp[i] = original_array[i];
    }
    std::cout << "line 23: ";
    print_array(temp, capacity*2);

//    delete[] original_array;
    original_array = temp;
    std::cout << "line 27: ";
    print_array(original_array, capacity * 2);
    capacity = capacity * 2;
}

bool insert (int array[], unsigned int & maxSize, unsigned int & nFilled, unsigned int pos, int value){
    while (maxSize < pos){
        grow(array, maxSize);
        print_array(array, maxSize);
    }
    for(unsigned int i = nFilled - 1; i >= pos; i = i-1){
        array[i+1] = array[i];
    }
    array[pos] = value;
    print_array(array, maxSize);
    return true;
}

Here's some sample input and what my program outputs right now:

int main() {
    unsigned int my_size = 4;
    int new_array[4] = {1,2,3,4};
    unsigned int nFilled = 4;

    insert(new_array, my_size, nFilled, 5, 15);
    print_array(new_array, my_size);
    return 0;
}

Output:

line 18: {0, 0, 0, 0, 0, 0, 0, 0}
line 23: {1, 2, 3, 4, 0, 0, 0, 0}
line 27: {1, 2, 3, 4, 0, 0, 0, 0}
{1, 2, 3, 4, 0, 0, 0, 0}
{1, 2, 3, 4, 0, 15, 0, 0}
{1, 2, 3, 4, -152629248, 32758, 0, 8}

the second to last line is inside the function and the last one is outside the function. I need these to be the same

Any help is appreciated - the TA's and professors are being unhelpful

Thanks

10
  • 4
    Sounds to me like you have some question to ask your instruction or teacher. If I had "have no clue how they want me to do this", that's where I would direct my questions to. Your instructor/teacher is paid to help you learn C++, this is their job. Commented Jan 17, 2023 at 20:43
  • 1
    Can you show us the code that is calling these functions? Commented Jan 17, 2023 at 20:50
  • 4
    int new_array[4] = {1,2,3,4}; is not a dynamically allocated array. You can never change its size or swap it for a different sized array. Passing new_array to grow() or calling delete on it is invalid. You evidently need to start out with a dynamically allocated array for this exercise which seems to be implementing something like std::vector( which is provided in the standard library). Commented Jan 17, 2023 at 20:57
  • 2
    Note that pointers just hold an address. They know where an object could be. they cannot know where that object came from, how it needs to be disposed of, or even if the object exists. You often have to do a lot of extra thinking and book-keeping when working with pointers. Commented Jan 17, 2023 at 21:02
  • 2
    You should review your lessons material and search for either new or std::unique_ptr (sooner or later you'll find std::vector). If they have talked you about malloc or realloc you may be in the wrong class. Commented Jan 17, 2023 at 21:05

1 Answer 1

4

There's two problems with your code working as written, the first one is that you can't reassign the value of new_array in main as written. As written it is not dynamically allocated, and so it cannot be changed. You will need to change that to be dynamically allocated:

int* new_array = new int[4];

for(int x = 0; x < 4; ++x)
{
    new_array[x] = x + 1;
}

That will address one issue, however the code still won't work, and that has to do with how variables are passed to insert and grow.

Your grow() function takes int*& a reference to a pointer to integer. This means that the underlying value passed in can be changed. However, your insert() function takes int[] an integer array that decays to to pointer to integer, and changes here will not be reflected at the call site of insert().

You can verify that by adding some more debugging statements:

bool insert (int array[],
    unsigned int & maxSize,
    unsigned int & nFilled,
    unsigned int pos,
    int value)
{

    // unchanged above...
    std::cout << "Inside insert: " << array << '\n';
    return true;
}


int main()
{
    // unchanged above...
    std::cout << "After insert: " << new_array << "\n";
    print_array(new_array, my_size);
    return 0;
}

You will get output similar to this:

line 18: {0 0 0 0 0 0 0 0 }
line 23: {1 2 3 4 0 0 0 0 }
line 27: {1 2 3 4 0 0 0 0 }
{1 2 3 4 0 0 0 0 }
{1 2 3 4 0 15 0 0 }
Inside insert: 0x548ed0
After insert: 0x548eb0
{1 2 3 4 0 0 49 0 }

Note that the array "Inside insert" and "After insert" are different.

To fix this, you need to make sure you pass something to insert() that allows for changing the value, similar to what was done for grow().

That change is as simple as changing the signature of insert() as follows:

bool insert (int *&array,
    unsigned int & maxSize,
    unsigned int & nFilled,
    unsigned int pos,
    int value)

Note the first parameter to insert() was changed to match the type in grow() a reference to pointer to integer. Now when we pass the pointer new_array to insert() a reference to that pointer is passed (which allows the value to be changed), and that is also passed to grow() (if necessary), allowing this to propagate all the way to the call site.

Be aware though there are stylistic problems with this approach -- unclear ownership semantics, potential for memory leaks (present in the posted code) etc.

I will also caveat that "reinventing" this type of data structure instead of using std::vector is not a good practice, however it does have its uses in a teaching context.

Sign up to request clarification or add additional context in comments.

2 Comments

Most of my programming experience is in python so this is going to sound dumb, but dynamically allocating memory for a variable in c++ seems like it's just a way to be able to change the variable however we want to, right?
It's not dumb, but it's not really something we can cover in depth in a comment. I'm sorry you're not getting the support from your Prof/TA, but I would suggest a good book: stackoverflow.com/questions/388242/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.