Function which uses array of pointers - c++

I have got this question on my c++ homework.
Write and test the function location that takes, as shown below, a
table of pointers to integers p, the size of such a table n and an
integer value x.
int* location (int* p [ ], int n, int x);
location searches the set of integers pointed at by the table of
pointers p for a match to the value of x. If a matching integer is
found, then location returns the address of that integer, NULL
otherwise.
I'm not sure that I fully understand the question. However, I tried to solve it but I got error(the program crashes). Here is my code.
#include<iostream>
using namespace std;
int* location (int* p [ ], int n, int x);
void main(){
int arr[3]={1,2,3};
int *ptr=arr;
int *address= location (&ptr, 3, 2);
cout<<&arr[3]<<" should be equal to "<<address<<endl;
}
int* location (int* p [ ], int n, int x){
for(int i=0; i<n; i++){
if(*p[i]==x){return p[i];}
}
return NULL;
}
Can someone please show me my mistake or tell me if I'm solving the question correctly?
Thanks

This is not correct in your code:
cout<<&arr[3]<<" should be equal to "<<address<<endl;
You are accessing array element with index 3, however, maximum index you can access in your case is 2. Also, there is alternative solution below.
Also the way you are passing pointer to a pointer to your location function (and also using it) is wrong. Because for example you haven't declared array of pointers to integers in the first place.
You can try to read somewhere a bit more on the notion of array of pointers in C++, in order to better understand the example below.
#include <iostream>
using namespace std;
const int MAX = 3;
int* location (int* p [ ], int n, int x);
int main ()
{
int var[MAX] = {10, 100, 200};
// Declare array of pointers to integers
int *ptr[MAX];
for (int i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; // Store addresses of integers
}
int *x = location(ptr, MAX, 100); // Now you have pointer to the integer you were looking for, you can print its value for example
if(x != NULL) cout<<*x;
return 0;
}
int* location (int* p [ ], int n, int x)
{
for(int i = 0; i<n; i++)
{
if(*p[i] == x) return p[i];
}
return NULL;
}

Related

2d Array to a function expecting int** array as parameter

I want to use a function made for dynamic arrys for an pre-initialised array too.
int MinInRow(int** fieldArray, int value, int currentColumn, int maxNumColumns)
{
int minVal = 0;
for (int inkrCol = 0; inkrCol < maxNumColumns; inkrCol++)
{
if (feldArray[currentColumn][inkrSpalte] < value)
{
minVal = feldArray[currentColumn][inkrCol];
}
}
return minVal;
}
So if I try
int testArray[3][4] =
{ {4,5,6,7},
{0,1,2,3},
{9,8,10,11}, };
int (*bufferArray)[4] = testArray;
or...
int** bufferArray = testArray;
or...
...
int main()
{
/*
read in other needed parameters
....
*/
std::cout << MinInRow((*bufferArray)[4], int value, int currentColumn, int maxNumColumns);
retrun 0;
}
I cant compile. But shouldnt int** bufferArray = testarray; just work fine? I mean there is always an double pointer to the first address of an 2D-Array.
how can I hand it over to the MinInRow-function? Thanks!
There is a little problem. "*" That one tell you that you want to make a pointer, but a pointer doesn't want a variable, he want the address. And then you've written
int** bufferArray = testarray.
You should write
int* bufferArray = new int [size of array] It's for 1D array
and ....
int** bufferArray = new int* [rows];
for (size_t = 0 ; i != rows ; ++i){
bufferArray[i] = new int [colons];
}
for 2D array
"I cant compile. But shouldnt int** bufferArray = testarray; just work fine? I mean there is alway an double pointer to the first address of an 2D-Array."
And Yes, it will be work nice. If testarray already 2D array

Whats wrong with this one? C++ Array Pointer

It says:
[Error] invalid conversion from 'int*' to 'int' [-fpermissive] on line 9 col 5.
What was asked of me to do:
Make a program that would accept array of 10 integers and determine the highest and the lowest integers from the set of integers. Use pointer variables for the highest and lowest integer.
what i did:
#include<iostream>
using namespace std;
int main()
{
int kre_arr[10];
int *kre_p;
for(int k = 0; k<=10; k++)
{
kre_p[k] = &kre_arr[k];
}
int j,temp;
cout<<"Enter 10 Integers: ";
for (*kre_p=0; *kre_p < 10; *kre_p++)
{
cin>>kre_arr[*kre_p];
}
for(*kre_p=0;*kre_p<=10;*kre_p++)
{
for(j=*kre_p+1;j<=10;j++)
{
if(kre_arr[*kre_p] > kre_arr[j])
{
temp = kre_arr[*kre_p];
kre_arr[*kre_p] = kre_arr[j];
kre_arr[j] = temp;
}
}
}
for(*kre_p=0;*kre_p<=9;*kre_p++)
{
cout<<endl<<kre_arr[*kre_p];
}
}
code i did before adding pointer i dont seem to understand pointer that much.
#include<iostream>
using namespace std;
int main()
{
int kre_arr[10];
int *kre_p;
int i,j,temp;
cout<<"Enter 10 Integers: ";
for (int i=0; i < 10; i++)
{
cin>>kre_arr[i];
}
for(i=0;i<=10;i++)
{
for(j=i+1;j<=10;j++)
{
if(kre_arr[i] > kre_arr[j])
{
temp = kre_arr[i];
kre_arr[i] = kre_arr[j];
kre_arr[j] = temp;
}
}
}
for(i=0;i<=9;i++)
{
cout<<endl<<kre_arr[i];
}
}
Looking at what you are asked to do I think you just have to determine the highest and lowest int in the array and point to. You sort the array thats slower.
I think it should look like that:
#include<iostream>
using namespace std;
int main()
{
int kre_arr[10];
int *low;
int *high;
cout<<"Enter 10 Integers: ";
for (int i=0; i < 10; i++)
{
cin>>kre_arr[i];
}
//determine the lowest
low=&kre_arr[0];
for(int i=1;i<10;i++)
{
if(kre_arr[i] < *low)
{
low=&kre_arr[i];
}
}
//determine the highest
high=&kre_arr[0];
for(int i=1;i<10;i++)
{
if(kre_arr[i] > *high)
{
high=&kre_arr[i];
}
}
cout<<"lowest: "<<*low<<"\nhighest: "<<*high;
}
kre_p[k] = &kre_arr[k];
kre_arr is array.
kre_arr[k] is integer.
&kre_arr[k] is integer address ( similar int*)
kre_p is pointer.
kre_p[k] is integer.
So, as a result, you cannot pass directly int* to int.
I guess you want kre_p+k = &kre_arr[k]
Given the state of your code, I fear for your life... So, for your overal survival, and of course in the hopes that you will learn something:
Never use 'using namespace std'. It's bad form.
You are not allocating memory for your array of pointers (kre_p). That will cause your program to crash for sure.
You don't actually need an array of pointers. Your array elements can be conveniently referred to by their offset in the array.
You are doing what appears to be a bubblesort to find the lowest and highest value. That's incredibly inefficient, and completely unnecessary.
C++ can be such a nice language. It bothers me when teachers seem to think they should be teaching it in a form that's as ugly as possible. Consider:
#include <algorithm>
#include <array>
#include <iostream>
int main () {
std::cout << "Enter 10 Integers: ";
std::array<int, 10> kre_arr;
for (auto &Val : kre_arr)
std::cin >> Val;
const int Low = *std::min_element (kre_arr.begin (), kre_arr.end ());
const int High = *std::max_element (kre_arr.begin (), kre_arr.end ());
// The assignment calls for pointers, so let's not disappoint.
const int *LowPtr = &Low;
const int *HighPtr = &High;
}

Segmentation fault from accessing 2d array passed to a function

I am using Code:Block.
Compiled the following code(no errors) and while running got segmentation fault.
void print(int size, int **a)
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";/**Segmentation fault here**/
}
cout<<endl;
}
}
int main()
{
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int size = sizeof(a)/sizeof(a[0]);
print(size,(int **)a);
return 0;
}
I tried using different methods of passing the array:
void print(int size, int a[][4])
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int size = sizeof(a)/sizeof(a[0]);
print(size,a);
return 0;
}
I got no error, code ran successfully.
For the first code instead of using a[i][j], I tried with *(*(a+i)+j), got segmentation fault.
Then I debugged the first code at the point of segmentation fault and absorbed the following:
> p a
$1 = (int **) 0x22fd30
> p *a
$2 = (int *) 0x200000001
> p **a
Cannot access memory at address 0x200000001
I believe that a hold the first address of the 2d array. but for p **a there is a different address shown in the error message.
Then I ran the first code in http://ideone.com/ and encountered run time error. Where am I making mistake? and why the debugger showing different address?.
In your first example
void print(int size, int **a)
expects second argument of type pointer to pointer to int. But here
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
print(size,(int **)a);
you pass a variable of type array of 4 arrays of 4 ints. When you pass an array to function, array decays to pointer to its first element. So actually function print gets argument of type int *[4] - pointer to array of 4 ints which is not what print expects. That's an error. You hide this error from compiler telling him that a has type int **. It doesn't. Hence the segmentation fault.
In your second example
void print(int size, int a[][4])
expects an argument of type array of arrays of 4 ints. It decays to int *[4] which is exactly the type of a when it decays while passed to print function. No error here.
If you index an int**, in your case a[0] for example, the resulting type is int*. If you index that again, as in a[0][0], it will interpret the first element (being the integer 1) (or first two elements on 64-bit) as a pointer to int (int*) and attempt to dereference it, which is obviously incorrect and will usually lead to a segmentation fault.
Your C-style cast (int**) is translated to a reinterpret_cast. Which is why I don't like C-style casts as it's not always obvious what they do.
In short: with your cast to (int**) you're telling the compiler that it's an array of pointers to int, which it isn't: it's an array of int[4]'s.
Edit: my comment about 64-bit only holds for platforms where sizeof(int) is always 4. I believe on linux sizeof(int) == sizeof(int*).
Replace cout<<a[i][j]<<" "; with cout<<a[i*size+j]<<" ";
Problem you are facing is because of Data type of both is different. int arr[][] is different from int ** arr. Lets see from 1-d array when you declare int arr[], arr it is same as int *arr. When you try to access it arr[i] internally what compiler does *(arr+i). But when you declare int arr[][size] data type of arr is int (*arr)[size] which is different from int **arr. That's why you get error. see this Link
The following works for me:
Allocation and assignment:
int** foo( int N, int M)
{
int** arr;
arr = (int **)malloc(sizeof(int *)*N);
for(int i=0; i < N; i++) {
arr[i] = (int *)malloc(sizeof(int)*M);
}
int x=0;
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
arr[i][j]=x;
x++;
}
}
return arr;
}
Now you can use it like this:
void print(int size, int a[][4])
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
int N=2;
int M=3;
int** foo = bar(N,M);
print(arr,N,M);
}

passing modified array values back to main function in C++

Write a reverse function that takes an integer array and its length as arguments. Your
function should reverse the contents of the array, leaving the reversed values in the original
array, and return nothing.
#include<iostream>
using namespace std;
void printArray(int a[], const int n)
{
for(int i=0;i<n;i++)
{
cout<<a[i];
i!=n-1 ? cout<<", " : cout<<"";
}
}
void reverse(int a[], const int n)
{
int reverse[n];
for(int i=0;i<n;i++)
{
reverse[n-1-i]=a[i];
}
a = reverse;
}
int main()
{
int *a,n;
cin>>n;
a = new int[n];
for(int i=0;i<n;i++)
a[i]=0;
a[0]=1;
reverse(a,n);
printArray(a,n);
delete [] a;
a = NULL;
return 0;
}
After calling reverse function the array from main is not modifying, please advice! :(
You can't assign one array to another. Instead copy from reverse to back into a:
std::copy(reverse, reverse + n, a);
Or possibly
memcpy(a, reverse, n * sizeof(int));
You are not copying the data from reverse back to a - you are instead pointing it (a) to a memory location that will no longer exist (be valid) after your function returns. You need to copy the values from reverse back to a. And I would recommend not using the same name for a function and a variable.
Try
void reverse(int a[], const int n)
{
int reverse[n];
for(int i=0;i<n;i++)
{
reverse[n-1-i]=a[i];
}
for(int i=0;i<n;i++)
{
a[i]=reverse[i];
}
}
As was pointed out in comments, the above shows one way of getting the reversed data into array a. It is not the only way - memcpy is considered a more efficient function to use. Even more efficient would be to do in place reversal - this would require a loop of just n/2 iterations while the above loops for 2n and is thus about 4x less efficient.
I recommend that you study all the answers provided - they highlight different aspects of memory handling, code efficiency etc.; something to learn from all of them.
Pointers! They're really useful.
void reverse (int *a, const size_t n)
{
int *b = a + n - 1;
while (b > a)
{
const int swap_value = *a;
*a = *b;
*b = swap_value;
++a;
--b;
}
}
Aha, you know you should pass int a[], a pointer to a, to reverse(), but you still encounter the same problem. You can't modify the pointer stored in a, unless you pass &a to reverse().

C++: Segamentation fault when reading array in function passed as argument

I get a segmentation fault when reading the second element of h array inside the g function. Strangely, when debugging can I actually watch the array content. I think that besides this curious thing that shows that the data is there, I have done something wrong. Thanks in advance.
#include <iostream>
using namespace std;
void function(void function_passed(double* [], int), int n);
void g(double* [] ,int n_g);
int main()
{
function(g,5);
return 0;
}
void g(double* h[], int n_g)
{
for (int i = 0; i < n_g; i++)
cout << i << " "<< *h[i] << endl;
}
void function(void function_passed(double* [], int ), int n)
{
double * h = new double[n];
for (int i=0;i<n;i++)
h[i] = i + 10;
function_passed(&h,n);
delete[] h;
}
void func(void g(double* [],int n ), int n)
{
double * h = new double[n];
for (int i=0;i<n;i++)
h[i] = i;
g(&h,n);
delete[] h;
}
Operator precedence has bitten you. Inside g:
*h[i] is parsed as *(h[i]) but what you want is (*h)[i].
*h[i] is okay for the first iteration, but in the second one (and all subsequent) you're dereferencing an invalid pointer h+i.
On the second thought, you're actually invoking undefined behavior - pointer arithmetic is valid only between pointers that point to the same array.