Can someone tell me how this compiles. How can you assign an integer array element to a pointer array element? The weird this is that the output suggests that nums[i] is an integer rather than a pointer, however nums was defined as a pointer.
#include <iostream>
int main() {
int n;
int *nums = NULL;
nums = new int[n]; // Assign pointer nums to a address in heap allocated for a integer array of n-elements.
n=5;
int Array[n] = {5,4,3,6,8};
for(int i=0; i<n; i++)
{
nums [i] = Array[i];
std::cout << nums[i] << " , " << &nums[i] << std::endl;
}
delete []nums;
return 0;}
I get the following output:
5 , 0x786cd0
4 , 0x786cd4
3 , 0x786cd8
6 , 0x786cdc
8 , 0x786ce0
Thanks for any help
How can you assign an integer array element to a pointer array element?
nums is a pointer to a dynamic array of int elements, in this case to the 1st int in the array. Dereferencing nums[i] yields an int& reference to the ith element in the array.
Array is a fixed array of int elements. When a fixed array is accessed by its name, it decays into a pointer to the 1st element. So, dereferencing Array[i] also yields an int& reference to the ith element in the array.
Thus, nums[i] = Array[i]; is simply assigning an int to an int. Nothing weird about that.
the output suggests that nums[i] is an integer rather than a pointer
That is correct, it is.
however nums was defined as a pointer
That is also correct. It is a pointer to an int, in this case the 1st int in the dynamic array.
Also, on a side note, your code has undefined behavior because n is uninitialized when used to allocate nums, and int Array[n] is non-standard behavior since n is not a compile-time constant.
Related
I read how to pass 2-D arrays in a function as a parameter and tried to implement the same. There are two problems which I encountered:
1) The first line of the output of the code contains garbage value.
2) What does the line ((arr + in) + j) actually do ? I mean, Why can't we do something like ((arr + i) + j) to access arr[i][j] ?
I also tried passing the matrix using parameter int **arr and then tried printing the value as arr[i][j] but there was no output.
Here is the output that I get:-
Enter number of nodes: 4
0167772161878012032-1
0000
0000
0000
And here is my code :-
#include <iostream>
using namespace std;
void show(int* arr, int n)
{
int i, j;
for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
cout << *((arr + i*n) + j);
}
cout << endl;
}
}
int main()
{
int n, i, j;
cout << "Enter number of nodes: ";
cin >> n;
int arr[n][n] = {{0}}; //Will initialize all elements in the matrix with 0.
show((int*)arr, n);
}
The biggest problem here is that you are using C and not C++.
To avoid people gasping and starting religious or political discussion, let's nail it down to:
VLAs (Variable Length Arrays) are not allowed in C++.
Additionally, you should never use raw pointers for owned memory and no pinter arithmetic.
And then the main topic:
Issue in Passing a 2-D array
The used syntax for passing arrays to function is wrong. In C++ arrays can be passed by reference or by pointer. Please see:
void function1(int(&m)[3][4]) // For passing array by reference
{}
void function2(int(*m)[3][4]) // For passing array by pointer
{}
int main()
{
int matrix[3][4]; // Define 2 dimensional array
function1(matrix); // Call by reference
function2(&matrix); // Call via pointer
return 0;
}
Of course we can do all kind of dirty designs with pointers. Even accepting pointer decays. But we should not do it.
Variable length arrays is not a standard C++ feature.
Nevertheless you passed to the function a pointer to the first element of a two-dimensional array.
Each "row" of the two-dimensional array has n elements. So if you have a pointer to the first element of the first row then to get the pointer to the first element of the second row you have to write
arr + n
If you want to get the first pointer to the i-th row of the two-dimensional array you have to write
arr + i * n
To get pointer to an element within the row you have to write
( arr + i * n ) + j
that is the same as
arr + i ( n + j
to get the element pointed to by the pointer you have to dereference the pointer
*( arr + i * n + j )
i have this code snippets
const int col= 5;const int row= 5;
int a[row][col] = {0};
int (*p)[col] ;
p = a;
And these statements print the same address
cout <<p;
cout << endl;
cout << *p;
in my opinion since p points to an array of 5 ints, dereferencing it
should give the first value which doesn't seem to be the case.
help!
since p points to an array of 5 ints
That much is correct.
dereferencing it should give the first value
No, it's type is "pointer to array"; dereferencing that gives "array", which decays to an int* pointer when you do just about anything with it - including printing it.
If you had a pointer to int
int * p = a;
then *p would indeed give the first array element.
I am practicing pointers by creating a Big Number struct, which has numDigits (number of digits) and digits (contents of the big number).
I create a function called removeZero(). After passing the integer array and the size n into it, because of passing by reference, I am supposed to cut down the leading zeros for my input. It works, when the integer array is in main function. However, when I pass an array that is in readDigits, it does not return with a non-leading-zero version. Why? How to fix it?
struct BigNum{
int numDigits;
int *digits; //the content of the big num
};
int main(){
int A[] = {0,0,0,0,0,0,1,2,3};
int n=9;
int *B=A;
//removeZero(A,n); If I use this, it cannot compile
//error: invalid initialization of non-const reference of type ‘int*&’ from an rvalue of type ‘int*’
removeZero(B,n);
for (int i=0; i<n; i++){
std::cout << *(B+i) << std::endl;
}
BigNum *num = readDigits();
return 0;
}
BigNum* readDigits(){
std::string digits;
std::cout << "Input a big number:" << std::endl;
std::cin >> digits;
//resultPt in heap or in stack?
int *resultPt = new int[digits.length()]; //in heap
int n = digits.length();
toInt(digits,resultPt);
removeZero(resultPt,n);
//Output the leading zeros, why?
for (int i=0; i<n; i++){
std::cout << *(resultPt +i) << std::endl;
}
BigNum *numPtr = new BigNum();
numPtr->numDigits = n;
numPtr->digits = resultPt;
return numPtr;
}
void toInt(std::string& str, int *result){
for (int i=0;i<str.length() ;i++ ){
result[str.length()-i-1] = (int)(str[i]-'0');
}
}
void removeZero(int* &A,int& n){
int i=0;
while (A[i]==0){
i++;
}
A=A+i; //memory leak?
n=n-i;
}
bool areDigits(std::string num){
for(int i=0;i<num.length();i++){
if(num[i]<'0' || num[i] >'9'){
return false;
}
}
return true;
}
Note that an array and a pointer are two different things. When you pass an array to a function, it degrades to a const pointer. This means that you cannot pass an array to a function which expects a int*&.
It could be the problem of scope of numPtr.numPtr is local variable of function readDigits(). Instead of returning pointer. Pass num to readDigits().
The signature of your removeZero function is:
void removeZero(int* &A,int& n);
That means the forst parameter is a reference of a pointer but the pointer is a non-const one, and you cannot therefore pass an array there, as array is a constant pointer (starting address cannot be changed).
In fact you are changing the starting address within removeZero.
With removeZero, the while loop shopuld be changed from:
while (A[i]==0){
to:
while ((A[i]==0) && (i<n)){
You have a logic error in toInt.
void toInt(std::string& str, int *result){
for (int i=0;i<str.length() ;i++ ){
// This stores the digits in the reverse order.
result[str.length()-i-1] = (int)(str[i]-'0');
}
}
That line should be
result[i] = (int)(str[i]-'0');
If you intend to keep the digits in reverse order, then removeZero has to be changed keeping that in mind.
`
When you say
int *B=A;
you are just creating a pointer to point to the same memory
of the Array A. Just by incrementing the pointer(*B) within the function
removeZero
A=A+i;
you are not deleting anything but you are just incrementing the pointer(*B)
to point to subsequent memory location within the array.
The original array memory pointed to by A remains the same, since you
have not changed any contents of the array, but you have just
incremented a pointer pointing to the same memory location as that of the array.
Also there are so many problems, like "Debasish Jana" mentioned,
you have to change your while loop. ""Code-Apprentice" gave you the reason for your
compilation error when you uncomment your commented code.
Also within "removeZero" you are incrementing A by i instead of "1" like
A=A+1;
This is one of the reason for the strange behavior you experience
Even after changing all this, you cannot see your array getting changed,
since you are not modifying any of the contents of your array.
If you really want to delete the contents of the array and change it dynamically,
you have to go for Vector<>. With static memory allocation you cannot cut the
array size short by removing some elements here and there. Learn Vector<>!
I having some issue when it comes to initializing pointers.
void findMM (int *PMM, int *theG)
{
// code I haven't written yet. It will essentially take two variables from //theG and store it in MM
}
int main()
{
int size;
int MM [2] = {1000, 0};
int *theG = NULL;
cout << "\nPlease insert size of array:" << endl;
cin >> size;
theG = new int [size];
findMM(&MM, &theG); //Get error with &MM
delete [] theG;
return 0;
}
The complier says that argument of type int (*)[2] is incompatible with parameter of type int ** So obviously that I have issue with the code in particular my (reference?) of array MM. Or perhaps there is other obvious faults that I am missing?
Edit attempt 2
void findMM (int *PMM, int *theG)
{
PMM [1] = 5;
theG [0] = 7;
}
int main()
{
int size;
int MM [2] = {1000, 0};
int *theG = NULL;
cout << "\nPlease insert size of array:" << endl;
cin >> size;
theG = new int [size];
findMM(MM, theG);
cout << MM [1] << endl << theG[0];
delete [] theG;
return 0;
}
The output would be 5 and 7 correct?
Since MM is an array, &MM is a pointer to an array (that's the type int (*)[2] that you see in the error). Instead, you seem to want to pass a pointer to the first element of the array. There are two ways to do that. Firstly, you can explicitly get the first element and then take the address of it: &MM[0]. Secondly, you can rely on array-to-pointer conversion to do it for you and just pass MM. Array-to-pointer conversion converts an array to a pointer to its first element.
I know this question has already been answered but I believe I can contribute to the asker's understanding.
Let's start with the basics:
void main()
{
int a = 2; // a is an int
cout << a << endl; // print 2
int *b; // b is a pointer-to-int
b = &a; // store the address of a in b
cout << *b << endl;// print the value that b points to, which is 2
int my_array = new int[3]; // allocate an array with 3 integers
my_array[0] = 50; // store 50 in the first element of the array
my_array[1] = 51; // store 51 in the second element of the array
my_array[2] = 52; // store 52 in the third element of the array
cout << c[0] << endl; // print 50
some_function(my_array, 3); // explained below
}
Now let's see how to pass arrays into functions. Assume we want to have a function called some_function that receives an array.
void some_function(int *some_array, int size_of_the_array)
{
// use the array however you like here
}
The function some_function receives a pointer to an int (also known as "pointer-to-int"). The name of an array is always the address of its first element, so if a function expects a pointer to an int and you give it the name of an array of ints, you are actually giving it the address of the first element in the array (this is just C++ syntax rules). So the function now has the address of the first element in the array, it can do stuff like *some_array to access the first element in the array, but what if it wants to access the other elements? It adds 1 to the pointer it already has and then applies the * operator to it: *(some_array + 1). Let's say an int is 4 bytes, if you add 1 to a pointer-to-int, the result of this addition is a new pointer that points to a location in memory 4 bytes ahead, so *(some_array + 93) is the value in the 94th element of the array some_array (array elements are stored sequentially in memory). A shorthand notation for this is some_array[93]. So if you have int *some_array = new int[100];, then some_array is a pointer and some_array[93] is the same as *(some_array + 93), which is the 94th element in the array.
The address itself though is not enough, you also need to know the number of entries in the array so that you don't try to access an element past the end of the array. In this example, assume that some_function simply prints the contents of the array, so if you don't provide 3 as the second argument to the function then it will have no way of knowing when to stop adding 1 to the pointer it received in the first argument. Beware, however, that by passing an array to a function this way, you are not passing the function a copy of the array, you are simply telling it where to find its contents in memory.
my aim is to reverse an array 3,12,2,1 to 1,2,12,3. when i run this code i get garbage before my actually result. i can't seem to see where the problem is please assit
#include<iostream>
using namespace std;
int rev (int arr[], int a){
//int r;
for(int i =a-1; i>=0; i--){
cout<<arr[i]<<" ";
}
return 0;
}
int main(){
int arr[] = {6,41,12,5,2};
cout<<"The rev of {6,41,12,5,2}"<<endl;
cout<<rev(arr, sizeof(arr))<<endl;
system("pause");
return 0;
}
Use sizeof(arr)/sizeof(arr[0]) instead of sizeof(arr).
sizeof(arr) gives the total size of the array. sizeof(arr[0]) is the size of one array element (all elements have the same size). So sizeof(arr)/sizeof(arr[0]) is the number of elements.
An optimized answer to the question would be using reverse () from STL if you are allowed to use it:
std::reverse
http://www.sgi.com/tech/stl/reverse.html
int main()
{
int arr[] = {6,41,12,5,2};
cout<<"The rev of {6,41,12,5,2}"<<endl;
reverse(arr, arr + 5);
copy(arr, arr + 5, ostream_iterator<int>(cout, ", "));
}
sizeof return the size in bytes. In your example, if sizeof(int) = 4, it returns 20.
Because you're using an array, you have to keep the size of the array handy as well. sizeof computes the size of a value in memory, in this case the size of all the memory used to represent arr. You can do sizeof(arr)/sizeof(int) to get the number of elements in an array. This makes sense because it's taking the total size of the array and dividing it by the size of an element in the array. Beware however that this only works for arrays (int arr[4] = {6,41,12,5,2};). If it's a pointer to a heap-allocated array via something like int* i = new int[4]; you'll need to keep the size of the array hanging around.
Also, you're calling your reverse function from within a cout<< call, which will print the function's return value (in this case it's hard-coded to 0).
It also turns out there is a function in the C++ standard library (std::reverse) that can do this.
If I may speak subjectively and in an off-topic manner about your approach, it is very un-C-like. My personal favorite way to reverse an array goes like this:
void reverse(int *a, int n)
{
int *p = a, *q = a + n - 1;
while (p < q)
{
int swap = *p;
*p++ = *q;
*q-- = swap;
}
}
// Usage:
int a [] = { /* ... */ };
reverse(a, sizeof(a)/sizeof(*a));
Of course, since your question is tagged c++, there's always std::reverse().
Sizeof operator return the one extra (arrayLength + 1) here 6 will return when passs 6 it store in a when a-1 you get 5 but array index start from 0 length-1 that from 0 to 4 here i pointing to index 5 that is not last element last+1 that why you got garbage value