I want to create an array of pointers, and each pointer should keep memory addresses of all elements from another array. But something is goind wrong.
Here is the code:
int main()
{
int a[] = { 1, 2, 3, 4, 5 };
int *b = new int[sizeof(a)];
for (int i = 0; i < sizeof(a); i++)
{
b = &a[i];
}
std::cout << &b[3] << std::endl;
std::cout << &a[3] << std::endl;
return 0;
}
When I expect is similar memory addresses, and values. Bt everything is different.
I think you wanted to do this
int main(int argc, char *argv[])
{
int a[] = { 1, 2, 3, 4, 5 };
unsigned max=sizeof(a) / sizeof(a[0]);
int **b = new int*[max];
for (int i = 0; i < max; i++)
{
b[i] = &a[i];
}
unsigned max=sizeof(a) / sizeof(a[0]);
for (int i = 0; i < max; i++)
{
std::cout << "b[" << i << "]:" << *b[i] << std::endl;
std::cout << "a[" << i << "]:" << a[i] << std::endl;
}
delete[] b;
return 0;
}
Two mistakes. First, when you declare array of pointers you use
int **b;
Secondly, to determine size of array you can use
sizeof(a) / sizeof(a[0])
but be careful here. After passing your array as argument into function it won't work any longer.
sizeof(a) returns the size IN BYTES of a.
To get the number of elements you should divide that for the sizeof(int).
So if you have 5 elements, for example, you'll have sizeof(a) equal to 5*sizeof(int). Divide that for sizeof(int) (which could vary depending on the machine you're working on) and you'll have the exact number of elements.
And I thing you wanna assign b[i] = &a[i], in order to store the addresses in the different elements of b.
Related
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.
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 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.
A memory leak exists in the following function. The trouble I am having is knowing how, when, where, and what to delete. Here is the code:
#include "stdafx.h"
#include <iostream>
void someFunc(double** ppDoubleArray, int length)
{
double* pNewDoubleArray = new double[length];
for(int i = 0; i < length; i++)
{
pNewDoubleArray[i] = 3 * i + 2;
}
*ppDoubleArray = pNewDoubleArray;
}
int main()
{
double dbls[] = { 1, 2, 3, 4, 5 };
double* pArray = dbls;
int length = sizeof dbls / sizeof dbls[0];
std::cout << "Before..." << std::endl;
for(int i = 0; i < length; i++)
{
std::cout << pArray[i] << ", ";
}
std::cout << std::endl;
someFunc(&pArray, length);
std::cout << "After..." << std::endl;
//Expected series is: 2, 5, 8, 11, 14
for(int i = 0; i < length; i++)
{
std::cout << pArray[i] << ", ";
}
std::cout << std::endl;
while(true){ }
return 0;
}
As you can see, I tried what to delete the new array I allocated after I had used it. It actually makes sense that this didn't work, but I am not sure what to do here..
Added delete[] pArray:
#include "stdafx.h"
#include <iostream>
void someFunc(double** ppDoubleArray, int length)
{
double* pNewDoubleArray = new double[length];
for(int i = 0; i < length; i++)
{
pNewDoubleArray[i] = 3 * i + 2;
}
*ppDoubleArray = pNewDoubleArray;
}
int main()
{
double dbls[] = { 1, 2, 3, 4, 5 };
double* pArray = dbls;
int length = sizeof dbls / sizeof dbls[0];
std::cout << "Before..." << std::endl;
for(int i = 0; i < length; i++)
{
std::cout << pArray[i] << ", ";
}
std::cout << std::endl;
someFunc(&pArray, length);
std::cout << "After..." << std::endl;
//Expected series is: 2, 5, 8, 11, 14
for(int i = 0; i < length; i++)
{
std::cout << pArray[i] << ", ";
}
delete[] pArray;
std::cout << std::endl;
while(true){ }
return 0;
}
Does this solve any, if at all memory leaks in this situation?
You are allocating & deleting an array in the function. And you are also returning it.
int main()
{
// This one is allocated on the stack, so it will be deleted when exiting main()
double dbls[] = { 1, 2, 3, 4, 5 };
double* pArray = dbls;
//...
// Your function allocates some memory now pointed at by pArray
someFunc(&pArray, length);
std::cout << "After..." << std::endl;
//Expected series is: 2, 5, 8, 11, 14
for(int i = 0; i < length; i++)
{
std::cout << pArray[i] << ", ";
}
std::cout << std::endl;
while(true){ }
// Your forgot to delete the memory allocated by your function!!! Memory leak!!!
return 0;
}
Here:
*ppDoubleArray = pNewDoubleArray;
delete[] pNewDoubleArray;
You delete the array that you just passed back to the caller. Don't do that delete! It is up to the caller to manage the memory after you pass it back.
Rather than jump through all these hoops, you should consider writing "real" C++ code, using container objects like std::vector which will manage the memory for you.
Did you mean to do this:
void someFunc(double** ppDoubleArray, int length)
{
for(int i = 0; i < length; i++)
{
*ppDoubleArray[i] = 3 * i + 2;
}
}
I don't understand why you'd allocate a new array if your intent is to modify the one passed in.
In someFunc you allocate array, then set pointer passed by the user, to point to it. Upon exiting the function, you delete that array and user ends-up with a pointer to freed memory.
You cannot delete pNewDoubleArray, as you store its address in ppDoubleArray. You have to delete[] pArray, when it is not used anymore or before setting it to another address (when calling someFunc(&pArray, ...) again).