I need help passing an array to a function by reference. The array is created beforehand being passed to the function but the value of the array after being passed through the function is not what I want - it remains unchanged. The code is shown below. The function is to take an array, a position p and a value val. The array is assumed to be sorted in ascending order up to position p and the value val must be placed such that the array is sorted in ascending order up to position p+1.
#include <iostream>
using namespace std;
// Function that takes an array a, a position,
// and a float value val to insert.
// a must already be sorted in acsending order
// up to p. val is then inserted such that
// the a is sorted up to p+1.
// p = 0 means position a[0].
void insert(double (&a)[], int aSize, int p, double val)
{
try {
// Throw error if p > size of array
if(p > aSize || p < 0) {
throw logic_error("Position is greater than size of array or less than zero.");
}
int newSize = aSize + 1;
double* vTemp = new double[newSize]; // create new bigger array
for(int i = 0; i <= p; i++) {
if(val >= a[i]) {
vTemp[i] = a[i];
} else {
vTemp[i] = val;
for(int j = i + 1; j < newSize; j++) {
vTemp[j] = a[j - 1];
}
break;
}
}
cout << "Size of vTemp = " << newSize << endl;
for (int k = 0; k < newSize; k++){
cout << "vTemp[" << k << "] = " << vTemp[k] << endl;
}
a = vTemp;
delete[] vTemp;
} catch(const logic_error& e) {
cout << "Error in input: " << e.what() << endl;
}
}
int main()
{
// Declare variables
double myArray[] = { 1, 2, 4, 8, 16, 20, 50, 30, 153 }; // sample array to test function
int p = 5; // position
double val = 7.2; // value to insert
int arraySize = sizeof(myArray) / sizeof(myArray[0]); // no. of elements in array
int newSize = 0; // size of expanded matrix
// Insert val
insert(myArray, arraySize, p, val);
cout << "Size of original array: " << arraySize << endl;
// Display new expanded matrix
newSize = sizeof(myArray) / sizeof(myArray[0]); // size of expanded matrix
cout << "Size of expanded array: " << newSize << endl << endl;
for(int i = 0; i < newSize; i++) {
cout << myArray[i] << " ";
}
cout << endl;
// Return success
return 0;
}
Don't use raw arrays. The class you are looking for is called std::vector (reference).
Just create a vector instead of an array and pass it by reference and you get what you need.
The problem doessn't come from the array being passed by reference.
The issues is assigning a dynamic array to a built-in array.
In the case above, when the following statement is executed.
a = vTemp;
The "array , which by that point is a pointer reference" will change is value to point to the dynamic array.
But don't forget that you are deleting the array.
delete[] vTemp;
you are not actually copying each element that the dynamic allocated array have into your array. when execution goes back to main, it points to your normal array.
Related
I have a class Array this class has functions like set values to an array index or get a value of an array index, i wanted to make an overloading operator function to add two Arrays objects and the result is one array which every element is the sum of the same index elements of the other two arrays like:
Array A={1,4,6}, Array B={1,20,3} c=A+B //c={1+1,4+20,6+3}.
the problem is that in the Sum Array object i am getting some random values instead of the sum values ,i think they are some addresses cus my overloading function somehow is not working properly.
public:
Array(int asize)
:size(asize)
{
Arr = new int[size];
}
Array(const Array &other) {
size = other.size;
Arr = new int[other.size];//
for (int x = 0;x < other.size - 1;x++)
Arr[x] = other.Arr[x];
}
Array operator+(const Array &other) {
Array t(*this);// creating new array with the values of the left hand Array
int ssize = (other.size < size) ? other.size : size;//if the right hand array size is
for (int x = 0;x < ssize;x++) //smaller than the left side(choose the smallest size)
{
t.Arr[x] += other.Arr[x];
}
return t;
}
~Array() {
delete[] Arr;
}
int get(int index) {
return Arr[index];
}
void set(int index, int value) {
Arr[index] = value;
}
int getSize() {
return size;
}
Array operator+(const Array &rhs) {//I also tried without const and without & sign
Array H(this->getSize());
for (int i = 0;i < this->getSize();i++)
{
H.Arr[i] = rhs.get(i)+this->get(i);//or rhs.Arr[i]+this->Arr[i];
}
return H;
}
private:
int size;
int *Arr;
};
and this is my main function:
std::cout << "\n enter the size of the Array" << std::endl;
int Size1;
std::cin >> Size1;
Array A1(Size1);
std::cout << "insert the elements starting of the first element of the Array" << std::endl;
int E1;
for (int i = 0;i < Size1;i++) {
std::cout << "Element number" << i + 1 << " is: " << std::endl;
std::cin >> E1;
A1.set(i, E1);
}
std::cout << "\nenter the size of the Array 2" << std::endl;
int Size2;
std::cin >> Size2;
Array A2(Size2);
std::cout << "insert the elements starting of the first element of the Array" << std::endl;
int E2;
for (int i = 0;i < Size2;i++) {
std::cout << "Element number" << i + 1 << " is: " << std::endl;
std::cin >> E2;
A2.set(i, E2);
}
Array sum(2);// I am currently trying with only 2 elements Arrays just to check if its working
sum = A1 + A2;
for (int i = 0;i < Size2;i++) {
std::cout << sum.get(i) << " , ";
}
In addtion to the copyt constructor, please note
Array sum(2);// I am currently trying with only 2 elements Arrays just to check if its working
sum = A1 + A2;
This mean you need also operator= to be defined for your code to work properly.
BTW if you write: Array sum(A2 + A2); instead of those two lines, this will work also with no operator=.
This findMax function returns max value from the array only if it is located at some index other than first index. I don't understand why because my findMin function that has almost the same code works perfectly fine.
void findMax(int array[5])
{
maximum = array;
for (i = 0; i < 5; i++)
{
if (*(array+i) > *maximum)
*maximum = *(array+i);
}
cout<<"Maximum element in the array is "<< *maximum << "\n" ;
}
This is my findMin fun that is working fine.
void findMin(int array[5])
{
minimum = array;
for (i = 0; i < 5; i++)
{
if (*(array+i) < *minimum)
*minimum = *(array+i);
}
cout<<"Minimum element in the array is "<< *minimum <<"\n";
}
The other answers have described how to do this more cleanly in C++. But to point out the actual bug: it's in this line.
*maximum = *(array+i);
You're not reassigning the maximum pointer to point to the maximum element, but rather you're never changing the pointer, but changing the value inside the array where maximum points to (i.e. array[0]). You meant this instead:
maximum = array + i;
The same issue is present in your findMin function as well.
First of all, as one of the comments on your question said this is mostly C way of doing things. In C++ you should use std::vector, std::min_element and std::max_element. It's easier and safer to use them instead of doing everything manually by yourself.
But, if you really want to do it yourself, try this code out, it should work:
void findMax(int array[])
{
maximum = array;
for (int i = 1; i < 5; i++)
{
if (*(array + i) > *maximum)
maximum = (array + i);
}
cout << "Maximum element in the array is " << *maximum << "\n";
}
void findMin(int array[])
{
minimum = array;
for (int i = 1; i < 5; i++)
{
if (*(array + i) < *minimum)
minimum = (array + i);
}
cout << "Minimum element in the array is " << *minimum << "\n";
}
This should work assuming that minimum and maximum are globally declared like this:
int * maximum;
int * minimum;
There are minmax_element tools for finding maximum and minimum, this is the most optimal variant of solving your problem - see the definition of the StdMinMax function.
But if you want to implement the logic yourself, I gave an example of a function, see the definition of the MinMax function
#include <iostream>
#include <algorithm>
void StdMinMax(int* arr, const unsigned int size)
{
std::pair<int*, int*> bounds = std::minmax_element(arr, arr + size); // or use auto bounds = ... ore auto [max, min] = ...
std::cout << "min : " << *bounds.first << " max : " << *bounds.second << std::endl;
}
void MinMax(int* arr, const unsigned int size)
{
std::cout << "Find max : " << std::endl;
auto currentMax = *arr;
for (int i = 1 ; i < size; ++i)
{
if (arr[i] > currentMax)
{
currentMax = arr[i];
}
}
std::cout << "Max : " << currentMax << std::endl;
std::cout << "Find min : " << std::endl;
auto currentMin = *arr;
for (int i = 1 ; i < size; ++i)
{
if (arr[i] < currentMax)
{
currentMin = arr[i];
}
}
std::cout << "Min : " << currentMin << std::endl;
}
int main()
{
const unsigned int size{5};
int array[size]{1, 3, 4, -11, 77};
StdMinMax(array, size);
MinMax(array, size);
return 0;
}
I have two arrays in a class, both with different sizes. My goal is to copy the second array (nArray) to the the first array (_theArray) using pointers. Below I have included the code of the function in the class, as well as the function in main to test the swap.
I have written the code below, where I try to point the first array to the second array using pointer p (int * p).
void easyArray::resize(unsigned int newSize)
{
// created new dynamic array
int * nArray = new int[newSize];
// init the new array
for (int i = 0; i < newSize; i++) {
nArray[i] = 0;
cout << nArray[i] << " ";
}
if (newSize >= _size) {
for (int i = 0; i < _size; i++) {
nArray[i] = _theArray[i];
}
} else {
cout << "not enough room" << endl;
}
destroy(); //deletes old array
int *p = _theArray; //points old to new array (?)
p = nArray; //sets old array = to new array (?)
}
in main:
void testResize()
{
easyArray a(5);
for(int i = 0; i < a.size(); i++) {
a[i] = i + 100;
}
a.resize(10);
a[9] = 99;
cout << "TEST RESIZE: " << a << endl << endl;
}
Any help is appreciated
Currently when I run this I get the error:
Debug Assertion Failed!
Expression:_CrtIsValiedHeadPointer(block)
Assuming _theArray is a class member variable, you can do _theArray = nArray after the call to destroy() and delete the last 2 lines involving p.
I am having some issues with an array expansion project and am trying to find where the issue is with getting my array to expand with all zeroes. Here are the requirements:
Array Expander. The program should have an array of integers. It will have a function that has two parameters, the integer array and the array’s size. This function will create a new array that is twice the size of the arguments array. The function should copy the contents of the argument array to the new array, and initialize the unused elements of the second array with 0. The function must return a pointer to the new array. The program will then display the contents of the new array.
Program must have the following functions
• int* expandArray(int[ ], int)
• void showArray(int [ ], int)
I am getting the program to build the first array without issues, however, the second array, while it displays the first array of numbers fine, displays the second array with an assortment of digits. I have been looking at this for hours and am at a loss with how to correct this to work correctly. Here is my code that I have so far:
//Include section
#include <iostream>
#include <cstring>
//Namespace Section
using namespace std;
//Function Prototype Section
int *expandArray(int[], int&);
void showArray(const int[], int);
//Main section: this is the entry point of the program, which controls the flow of execution
int main()
{
int arraySize = 7; //sets the size of the array at 7
int *array = new int[arraySize];
for (int c = 0; c < arraySize; ++c)
array[c] = c + 1;
//the following outputs the initial array of 7 to the user's screen; beginning at 1 and incrementing to 7
cout << "*********************************************************************" << endl;
cout << " The following is the initial array " << endl;
cout << "*********************************************************************" << endl;
cout << endl;
showArray(array, arraySize);
cout << endl;
cout << endl;
//the following outputs the initial array, plus expands the array by double, initializing the unused elements with zero
cout << "*********************************************************************" << endl;
cout << " The following is the expanded array " << endl;
cout << "*********************************************************************" << endl;
cout << endl;
showArray(array, arraySize * 2);
cout << endl;
cout << endl;
delete[] array;
system("PAUSE");
return 0;
}
int *expandArray(int array[], int &arraySize)
{
int *expandedArray;
expandedArray = new int[arraySize * 2];
for (int index = arraySize; index < (arraySize * 2); index++)
expandedArray[index] = 0;
arraySize *= 2;
delete[] array;
return expandedArray;
}
void showArray(const int arr[], int arraySize)
{
for (int index = 0; index < arraySize; index++)
cout << arr[index] << " " << endl;
}
I believe my issue is in the following section of the code, but unsure as to how to fix it:
int *expandArray(int array[], int &arraySize)
{
int *expandedArray;
expandedArray = new int[arraySize * 2];
for (int index = arraySize; index < (arraySize * 2); index++)
expandedArray[index] = 0;
arraySize *= 2;
delete[] array;
return expandedArray;
Any assistance would be greatly appreciated!
As I see it you forgot to to copy the contents of your initial array into expandedArray in the declaration of your function. You only set all elements with index in between arraySize and arraySize*2 to 0 but never actually copied the values of your argument.
I would include the following:
for(int i=0; i<arraySize; i++) expandedArray[i] = array[i];
right after having declared expandedArray dynamically. Note it is important that you include this piece of code before modifying arraySize as you would get out-of-bounds issues when accessing array[i].
The issue is that you're not copying the original array's contents into the new allocated array space.
A simple solution is to use new[] with brace initialization of 0, and then copy the original contents into the new array. The brace initialization will initialize all the space to 0, so you don't need to write two loop to set the newly allocated space to 0.
int *expandArray(int array[], int &arraySize)
{
int *expandedArray;
// allocate and initialize all entries to 0
expandedArray = new int[arraySize * 2]{0};
// copy old elements to new space
for (int index = 0; index < arraySize; index++)
expandedArray[index] = array[index];
// delete old space
delete [] array;
// double array size
arraySize *= 2;
return expandedArray;
}
int *arrayExpander(int arr[], int size)
{
int *expendedArray = new int[size * 2];
// move elements forom original array into the expandedArray
// initilize the rest of the elements to ZERO
for (int i = 0; i < size * 2; i++)
{
if (i < size)
{
// filling firt half
expendedArray[i] = arr[i];
}
else
{
// second half of the array
expendedArray[i] = 0;
}
}
return expendedArray;
}
int main()
{
int size = 5;
int arr[] = { 1,2,3,4,5 };
// Array pointer
int *arrPtr = arrayExpander(arr, size);
// Display
for (int i = 0; i < size * 2; i++)
{
cout << arrPtr[i] << " " << flush;
}
return 0;
}
Actually there are 2 errors in your code:
When you run your code it prints the first 7 elements of your array of type double correctly, but not the other 7. This is because they are not initialized, therefore they are returning garbage values.
Therefore in the function you have to initialize the other 7 elements to 0. The same goes for the first 7 elements and the first matrix.
I rectified the problem. Please have a good look at it:
//Include section
#include <iostream>
#include <cstring>
//Namespace Section
using namespace std;
//Function Prototype Section
int *expandArray(int[], int&);
void showArray(const int[], int);
int *expandedArray;
//Main section: this is the entry point of the program, which controls the flow of execution
int main()
{
int arraySize = 7; //sets the size of the array at 7
int *array = new int[arraySize];
for (int c = 0; c < arraySize; ++c)
array[c] = c + 1;
//the following outputs the initial array of 7 to the user's screen; beginning at 1 and incrementing to 7
cout << "*********************************************************************" << endl;
cout << " The following is the initial array " << endl;
cout << "*********************************************************************" << endl;
cout << endl;
showArray(array, arraySize);
cout << endl;
cout << endl;
//the following outputs the initial array, plus expands the array by double, initializing the unused elements with zero
cout << "*********************************************************************" << endl;
cout << " The following is the expanded array " << endl;
cout << "*********************************************************************" << endl;
cout << endl;
expandArray(array, arraySize);
showArray(expandedArray, arraySize);
cout << endl;
cout << endl;
delete[] array;
return 0;
}
int *expandArray(int array[], int &arraySize)
{
expandedArray = new int[arraySize * 2];
for (int c = 0; c < arraySize; ++c)
expandedArray[c] = c + 1;
for (int index = arraySize; index < (arraySize * 2); index++)
expandedArray[index] = 0;
arraySize *= 2;
delete[] array;
return expandedArray;
}
void showArray(const int arr[], int arraySize)
{
for (int index = 0; index < arraySize; index++)
cout << arr[index] << " " << endl;
}
//here is your solution bro..!!
I'm having trouble getting my code to return the correct arrays. void map takes in a function such as tiple and modifies the value that was passed into it from the array src and then returns the new value into dst which is then printed out. I can get the code to compile but it doesn't return the correct array. For example, when it takes in [1,2,3,4] it returns [0,3,6,9] instead of [3,6,9,12]
typedef int (*intModifier)(int);
int triple(int x){
return 3*x;
}
void map(intModifier func, int src[], int dst[], int length){
for(int *i = src; i < src + length; ++i){
dst[*i] = func(*i);
}
return;
}
void printIntArray(int arr[], int length){
cout << "{";
if (length > 0){
cout << arr[0];
}
for(int i = 1; i < length; ++i){
cout << ", " << arr[i];
}
cout << "}";
}
int main(){
int arr1[4] = {1, 2, 3, 4};
int arr2[4] = {0, 0, 0, 0};
int arr3[4] = {0, 0, 0, 0};
int arr4[4] = {0, 0, 0, 0};
cout << "Testing map." << endl;
cout << " setting arr1 = {1,2,3,4}" << endl << endl;
cout << " mapping from arr1 to arr2 using triple" << endl;
map(triple, arr1, arr2, 4);
cout << " arr2 = ";
printIntArray(arr2, 4); cout << endl << endl;
return 0;
}
Any help is appreciated. Thanks.
I am not sure why it is only the second element being modified. But the fact that is only one is almost definitely this:
void map(intModifier func, int src[], int dst[], int length){
for(int *i = src; i < src + length; i++){
dst[*i] = func(src[*i]);
return; // You return here!!!
}
}
You will always return from map during the first iteration of your for loop. See how beneficial it is to indent your code!
Your map function is what is causing most of the issues. Especially in the way you are trying to conduct the operations in the for loop.
void map(intModifier func, int src[], int dst[], int length){
for(int *i = src; i < src + length; ++i){ // There are some major issues in how you are
dst[*i] = func(*i); // iterating through the source array.
}
return;
}
You are using the value of the source array to increment and store data between your destination array and source array. Your arrays are only 4 int "blocks" yet you increment through source at the source base length plus 4 i < src + length which is going well past your array length.
It would be better if you iterate through using the length you pass in, that's essentially why you pass the length in correct? So you could use this:
void map(intModifier func, int src[], int dst[], int length){
for (int i = 0; i < length; i++) // Iterate until we have met the length of the source
{ // array. Pass the source array off to our triple func
dst[i] = func(src[i]);
}
return;
}
The function iterates through source and passes its contents to the triple func then stores it at the same location in our destination array.
EDIT: Credit given to 1201ProgramAlarm and Ben.