Вопрос

I've been trying to figure this out off and on for a week now and I keep running into problems.

My objective:

Write a function that allocates memory for an integer array. The function takes as an argument an integer pointer, the size of the array, and newSize to be allocated. The function returns a pointer to the allocated buffer. When the function is first called, the size will be zero and a new array will be created. If the function is called when the array size is greater than zero, a new array will be created and the contents of the old array will be copied into the new array. Your instructor has provided arrayBuilder.cpp as starter code for this programming challenge. In addition, Lab9_1.exe is the executable for this application which you can test.

The code:

#include <iostream>
using namespace std;

int * arrayBuilder(int * arr, int size, int newSize);
void showArray(int * arr, int size);

int main()
{
int * theArray = 0;
int i;

cout << "This program demonstrates an array builder function." << endl << endl;

// create the initial array.  The initial size is zero and the requested size is 5.
theArray = arrayBuilder(theArray, 0, 5);

// show the array before values are added
cout << "theArray after first call to builder: " << endl;
showArray(theArray, 5);

// add some values to the array
for(int i = 0; i < 5; i++)
{
    theArray[i] = i + 100;
}

// show the array with added values
cout << endl << "Some values stored in the array: " << endl;
showArray(theArray, 5);

// expand the size of the array.  size is not the original size.  newSize
// must be greater than size.
theArray = arrayBuilder(theArray, 5, 10);

// show the new array with the new size
cout << endl << "The new array: " << endl;
showArray(theArray, 10);

cout << endl;

delete [] theArray; // be sure to do this a1t the end of your program!

system("pause");

return 0;
}

/*
FUNCTION: arrayBuilder
INPUTS Pointer to an array.  Size of the array. If size is zero, arr can be    NULL.
      Size of the new array.
OUTPUTS:  Returns a pointer to allocated memory.  If newSize is greater than size,
      an array of newSize is allocated and the old array is copied into the new
      array. Memory pointed to by the old array is deleted.  All new elements
      are initialized to zero.
*/


int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here


return NULL; // default return value.  No memory allocated!
}

/*
FUNCTION: showArray
INPUTS: Pointer to an array.  Size of the array. If size is zero, arr can be  NULL.
OUTPUTS:  Prints the contents of the array to the console.
*/


void showArray(int * arr, int size)
{
cout << "arr = ";

for(int i = 0; i < size; i++)
{
    cout << arr[i] << "  ";
}

cout << endl;

}

My struggles: I cannot figure out how to switch "arr" and a temporary array's values.

int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
    int * temp = new int [newSize];

for (int i = size; i < newSize; i++)
{
        *arr = *temp;
        temp++;
}

return NULL; // default return value.  No memory allocated!
}

another attempt while searching for answers:

int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
int * temp = new int [newSize];
memcpy (temp, arr, size *sizeof(int));
// HINT: Design the function before writing it.
delete[]  arr;

for (int i = size; i < newSize; i++)
{
    temp[i] = i;
}

return NULL; // default return value.  No memory allocated!
}

Basically my end goal is to have the answer look like this:

This program demonstrates an array builder function.

theArray after first call to the builder:
arr = 0 0 0 0 0

some values stored in the array:
arr = 100 101 102 103 104

the new array:
arr = 100 101 102 103 104 0 0 0 0 0

PROGRESS!! Its not crashing anymore :-) This is where I'm at now:

This program demonstrates an array builder function.

theArray after first call to builder:
arr = -842150451  0  0  0  0

Some values stored in the array:
arr = 100  101  102  103  104

The new array:
arr = -842150451  -842150451  -842150451  -842150451  -842150451  -842150451  -8
42150451  -842150451  -842150451  -842150451

Press any key to continue . . .

I'll keep tinkering and let everyone know if I hit a wall! Thanks again guys!

OKAY! finally got it to display properly:

This program demonstrates an array builder function.

theArray after first call to the builder:
arr = 0 0 0 0 0

some values stored in the array:
arr = 100 101 102 103 104

the new array:
arr = 100 101 102 103 104 0 0 0 0 0

This is what I did. I feel like I may have cheated in the second part when i put 0 values in for "temp". It was my understanding that i was going to take the data from the previous array and put it into the new one, and instead I just remade it. (So it will only work with this particular set of values [only 0's]). Is there a different way I can code the second part so it works universally with whatever values are thrown at it???

int * arrayBuilder(int * arr, int size, int newSize)
{
int i = size;
int * temp = new int [newSize];
// What if the size is 0?
if (size <= 0)
{
    while (i < newSize)
    {
        temp[i] = 0;
        i++;
    }
}
// Assuming the size _isn't_ 0
else 
{
// "a new array will be created"  (good)

for (i = 0; i < newSize; i++)
{
    // The contents of the "old" array (arr) will be
    // copied into the "new" array (temp)
    while (i < size)
    {
        temp[i] = arr[i];
        i++;
    }
    while (i >= size && i < newSize)
    {
        temp[i] = 0;
        i++;
    }
    // as a hint, you can address the elements in 
    // both arrays using the [] operator:
    // arr[i]
    // temp[i]

}
}

// "The function returns a pointer to the allocated buffer."
// So, NULL is wrong, what buffer did you allocate?
return temp; // default return value.  No memory allocated!
}
Это было полезно?

Решение

Since you put forth some effort.

Write a function that allocates memory for an integer array.

The prototype for this function was provided for you:

int * arrayBuilder(int * arr, int size, int newSize);

The function takes as an argument an integer pointer, the size of the array, and newSize to be allocated. The function returns a pointer to the allocated buffer.

This says nothing about doing anything with the "old" (passed in) array, so we should assume it needs to be left alone.

When the function is first called, the size will be zero and a new array will be created.

The above text is meaningless given the context. Feel free to tell your instructor I said so. If the size is zero, how do you know how many elements to allocate?

If the function is called when the array size is greater than zero, a new array will be created and the contents of the old array will be copied into the new array.

OK, now the guts of what needs to be done (you're so close)

int * arrayBuilder(int * arr, int size, int newSize)
{
    // What if the size is 0?

    // Assuming the size _isn't_ 0
    // "a new array will be created"  (good)
    int * temp = new int [newSize];

    for (int i = size; i < newSize; i++)
    {
        // The contents of the "old" array (arr) will be
        // copied into the "new" array (temp)

        // as a hint, you can address the elements in 
        // both arrays using the [] operator:
        // arr[i]
        // temp[i]

        // something is wrong here...
        *arr = *temp;

        // you definitely _don't_ want to do this
        temp++;
    }

    // "The function returns a pointer to the allocated buffer."
    // So, NULL is wrong, what buffer did you allocate?
    return NULL; // default return value.  No memory allocated!
}

Другие советы

You already got the answer here:

memcpy (temp, arr, size *sizeof(int));

but you are making several other mistakes after that. Primarily, you need to return temp ; not return NULL ;

But also you don't need the loop after the delete arr[] ;

Also don't delete arr[] if size is zero.

This is horribly complex code. Programming is all about reducing complexity.

With that in mind, here’s a proper C++ solution:

std::vector<int> arr = {1, 2, 3, 4, 5};
std::vector<int> copy = arr;

That’s it. I hope this exemplifies why you should use the standard library (or other appropriate libraries) rather than re-inventing the wheel. From the code you’ve posted I am assuming that you’ve learned (or are learning) C++ from a horrible book or course. Trash that and get a proper book. C++ is complex enough as it is, no need to add needless complexity.

Just to help you realize why the first attempt didn't work:

*arr = *temp;

This is assigning a value to the old array, from the new array. That's backwards.

But it's just targeting the first value, *arr doesn't change. You increment *temp, but you also need to increment *arr. (Also, manual pointer manipulation like that horrifying and memcopy() is a lot better. But hey, this is for learning purposes, right?)

Also, think about that loop:

for (int i = size; i < newSize; i++)

That's iterating through once for each bit that newSize is bigger than size. But you're doing two things here. 1) Copying over data and 2) initializing the new data. That for loop you have is good for going over the new data, but it's not the loop you want for copying over the data you already have. That would go from zero to size, right?

And when you're done you need to return the address of the array you built.

return NULL; // default return value.  No memory allocated!

That's just some dummy mock code. It's a placeholder by the teacher. It's part of the code you're supposed to change.

Per your update:

I feel like I may have cheated in the second part when i put 0 values in for "temp"

Well what else were you going to put in there? You DO copy over the old array data. Then you EXPAND the array. What goes into the new territory? Zero values as a default is perfectly valid.

Is there a different way I can code the second part so it works universally with whatever values are thrown at it???

Well yes, but you'd have to actually have something to throw at it. Your ArrayBuilder function could take in additional arguments, possibly as a variadic function, so it knows what values to put into the new fields. But your function declaration doesn't have that. All it does is make the array bigger.

Also, in your last edit you've got those two while loops that iterate through i inside of a for loop which also iterates through i. That'll work, but just so you know it's a bit... uncouth. It's the sort of thing that'll get you in trouble when things get more complicated.

You could do this instead:

for (i = 0; i < newSize; i++)
{
  if(i < size)
  {
    temp[i] = arr[i];
  }
  else // if(i >= size && i < newSize) //Wait a sec, this "if" is superfluous. It's conditions are enforced the the first if and the loop condition.
  {
    temp[i] = 0;
  }
}

You should also probably delete the comments that make it sound like someone else wrote your code for you. Because someone else did your homework for you. It's best to

Finally, THOU SHALT INDENT THY CODE!

If I have correctly understood the assignment the function should look the following way. First of all I would substitute the function declaration

int * arrayBuilder(int * arr, int size, int newSize);

for

int * arrayBuilder( const int *arr, size_t size, size_t newSize );

Here is its definition

int * arrayBuilder( int * arr, int size, int newSize)
{
   int *tmp = 0;

   if ( newSize >= 0 )
   {
      tmp = new int[newSize] {};

      int copy_size = std::min( size, newSize );

      if ( copy_size > 0 ) std::copy( arr, arr + copy_size, tmp );
   }

   delete []arr;

   return tmp;
}

Try this:

Code:

#include <iostream>

using namespace std;

int a[3] = 
{
    1,
    2,
    3
};

int b[3];

int main ()
{
    cout << endl;
    cout << "Array #1 elements: " << endl;
    for(int i = 0; i < 3; ++i)
    {
        cout << a[i] << " ";
    }

    for(int i = 0; i < 3; ++i)
    {
        b[i] = a[i];
    }
    cout << endl << endl;
    cout << "Copying Array #1 elements to Array #2..." << endl;
    cout << endl;
    cout << "Array #2 elements: " << endl;
    for(int i = 0; i < 3; ++i)
    {
        cout << b[i] << " ";
    }
    cout << endl << endl;
    return 0;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top