Negative Subscript of an array in c++ - c++

Lets say we have an int array "arr" of size 5 then &arr points to whole array of 5 int.
But when I do like &arr[-1] I don't get any error, Can somebody explain what does this means.
int arr[5] = {1, 2, 3, 4, 5};
std::cout << &arr << std::endl; // 0x61fea0
std::cout << &arr[-1] << std::endl; // 0x61fe9c (0x4 less than previous)

This is because of the relationship that arrays and pointers share. A negative index might still point at an address within the bounds and won't result in an error

Related

what do (&p)[7] represent here?

Can anyone please explain!
While referring ArrayDecay, I was stuck at this...,
void fun(int (&p)[7])
{
cout << sizeof(p) << endl;
}
int main()
{
int a[7] = {1, 2, 3, 4, 5, 6, 7,};
cout << "Actual size of array is: ";
cout << sizeof(a) <<endl;
// Calling function by reference
fun(a);
return 0;
}
I know the difference between (*p)[] and *p[] and their functioning.
But, can't figure out what (&p)[] is!.
In the context of function argument declarations, the & means reference.
So the function fun accepts one argument, which is a reference to an array of 7 integer elements.
The comment should have been a pretty big hint:
// Calling function by reference
fun(a);

Pointers difference

Say I declared an arrayint a[]={1,2,3,4,5};, when I do (*(&a+1)-a), it prints 5.
I came to know that *(&a+1) takes me to the end of an array, and as sizeof(a)=20.
So does pointer arithmetic takes me ahead of size of allocated container?
Also I am little bit confused on pointer arithmetic, why it prints 5 rather than 20?
The result of pointer arithmetic is is in units of the dereferenced type.
If you have a pointer to an int then the units will be in int elements.
If you have a pointer to an int[5] then the units will be in int[5] elements, which are exactly 5 times as big.
For your program above, a and &a will have the same numerical value,and I believe that's where your whole confusion lies.You may wonder that if they are the same,the following should give the next address after a in both cases,going by pointer arithmetic:
(&a+1) and (a+1)
But it's not so!!Base address of an array (a here) and Address of an array are not same! a and &a might be same numerically ,but they are not the same type. a is of type * while &a is of type (*)[5],ie , &a is a pointer to (address of ) and array of size 5.But a as you know is the address of the first element of the array.Numerically they are the same as you can see from the illustration using ^ below.
1 2 3 4 5
^ // ^ stands at &a
1 2 3 4 5
^ // ^ stands at (&a+1)
1 2 3 4 5
^ //^ stands at a
1 2 3 4 5
^ // ^ stands at (a+1)
Hope this will clear the doubts.
Pointer arithmetic is not same as arithmetic operation (addition/subtraction) between hexadecimal values. Following example demonstrates both.
int main()
{
int a[] = { 1, 2, 3, 4, 5 };
int * pintx = *(&a + 1);
int * pinty = a;
cout << "pintx = " << pintx << endl;
cout << "pinty = " << pinty << endl;
cout << "Pointer Arithmetic : Ans = " << (*(&a + 1) - a) << endl;
// Prints 5
cout << "Pointer Arithmetic : Ans = " << (pintx - pinty) << endl;
// Save as above, Print 5
cout << "Hexadecimal Subtraction: Ans = " << ((int)pintx - (int)pinty) << endl;
// Prints 20, as you expect
return 0;
}
Hope this helps.
So does pointer arithmetic takes me ahead of size of allocated container?
No. Not the "size of allocated container", but the size of the dereferenced type. sizeof(a) is 20 because as an object the type of a is int[5] instead of int*, and the type of &a is int[5]*. It will be clearer if I rewrite your example as below:
typedef int Int5[5];
Int5 a = { 1, 2, 3, 4, 5 };
Also I am little bit confused on pointer arithmetic, why it prints 5 rather than 20?
(*(&a+1)-a) is 5 because in this case a is interpreted as int*.

Why is memory adress getting printed instead the values of array in c+.+

When I'm trying to print the values of an array, its memory location is getting printed instead of values. What am I doing wrong?
int main()
{
int list[3];
for (int i=0; i<3; i++)
{
list[i] = i;
std::cout<<list<<std::endl;
}
}
OUTPUT: 0x7ffffef79550
C++ doesn't provide an overload for arrays when using the iostream library. If you want to print the values of an array, you'll need to write a function or find one somebody else has written.
What's happening under the hood is list is decaying to an int*, and that's what you're seeing printed.
This looks like a typographical error:
std::cout << list
You want to print a specific element of the array, right?
std::cout << list[i]
When printing "the whole array" without index, the pointer to first element is printed (see the other answer for reason).
std::cout << list << std::endl;
You're printing the array object itself. What do you expect to see? The name of the array identifier? The address of the first element in the array? (actually this is what happens in your case). Or do you expect the array to neatly iterate over it's elements and build a comma separated string of all the values and output it to the stream? If this is what you want, you have to implement it yourself.
template <std::size_t N>
std::ostream& operator<<(std::ostream& out, int (&arr)[N]) {
std::copy(std::begin(arr), std::end(arr), std::ostream_iterator<int>{out, ", "});
return out;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
std::cout << arr << std::endl; // Ok, prints "1, 2, 3, 4, 5, ".
}
You need to dereference the list. Instead of:
std::cout << list << std::endl;
do:
std::cout << *list << std::endl;

C++ begin/end(arr) on a pointer - no matching function for call to ‘begin(int**&)’ [duplicate]

This question already has answers here:
error: no matching function for call to 'begin(int*&)' c++
(3 answers)
Closed 6 years ago.
I'd like to get length of an array. I have this code:
#include <iterator>
#include <iostream>
#include <string>
using namespace std;
void printArrLen(int arr[]);
int testArr [3] = {1, 4, 5};
int main() {
printArrLen(testArr);
cout << "main/testArr; Memory address: " << testArr << ", value: " << *testArr << endl;
cout << end(testArr) << endl;
}
void printArrLen(int arr[]) {
cout << "printArrLen/arr; Memory address: " << arr << ", value: " << *arr << endl;
cout << "printArrLen/testArr; Memory address: " << testArr << ", value: " << *testArr << endl;
// This works:
cout << end(testArr) << endl;
// This doesn't work - no matching function for call to 'end(int*&)':
// cout << end(arr) << endl;
// Doesn't work:
// cout << "arrLen: " << end(arr) - begin(arr) << endl;
}
Output:
printArrLen/arr; Memory address: 0x601318, value: 1
printArrLen/testArr; Memory address: 0x601318, value: 1
0x601324
main/testArr; Memory address: 0x601318, value: 1
0x601324
Uncommenting cout << end(arr) << endl; in printArrLen gives no matching function for call to 'end(int*&)'
I'm aware that begin/end(arr) wont work if arr is a pointer.
Why do they work on testArr in printArrLen and main, if the testArr seems to be a pointer too? How it can be proven in printArrLen that testArr is not a pointer and arr is while they both seem to contain a memory address?
I'm aware that begin/end(arr) wont work if arr is a pointer. Why do they work on testArr in printArrLen and main, if the testArr seems to be a pointer too?
Pointers are not arrays.
In your code,
testArr is array which has been initialised with 3 elements.
arr is array parameter. Array parameter is special in the sense that the array decays to pointer, so what is actually passed to the function printArrLen is a pointer (to arr first element).
Btw, you don't have to provide array size when you initialise it. This would do as well (and better):
int testArr[] = {1, 4, 5};
I'd like to get length of an array.
[...]
void printArrLen(int arr[]);
Not like this. arr in this function is actually a pointer to the first element of the array. Or more precisely, it may point to the first element of an array. It's just an int* and could point anywhere. In any case, there is no size information anymore inside of the function. You simply cannot get it.
The [] syntax is just there to confuse you. But don't take my word on it -- ask your compiler by trying this piece of code:
void printArrLen(int arr[]) {}
void printArrLen(int* arr) {}
You will see that it will complain about a redefinition.
int testArr [3] = {1, 4, 5};
testArr, in contrast to the arr parameter above, is an array, and carries the size information in its type.
int main() {
printArrLen(testArr);
Here you pass to the function a pointer to the first element of testArr, i.e. an int* pointing to the "1" element.
// This works:
cout << end(testArr) << endl;
Because testArr is an array.
// This doesn't work - no matching function for call to 'end(int*&)':
// cout << end(arr) << endl;
Because arr is a pointer.
Use std::vector if the array's size is only known at runtime, or std::array if it's already known at compile time. Both containers always know their own size.
How it can be proven in printArrLen that testArr is not a pointer
and arr is while they both seem to contain a memory address?
This question makes less sense than it seems.
Consider this:
int main()
{
int i = 0;
double d = 0.0;
}
Now, how can you "prove" that i is not a double but d is?
The answer is that you do not have to "prove" it, because, obviously, you already know.
Technically, there is another answer to your question, of course, and that is using typeid...
#include <typeinfo>
#include <typeindex>
#include <iostream>
void printArrLen(int arr[]);
int testArr [3] = {1, 4, 5};
int anotherTestArr [3] = {1, 4, 5};
int yetAnotherTestArr [4] = {1, 4, 5, 6};
int main() {
printArrLen(testArr);
}
void printArrLen(int arr[]) {
std::cout << (std::type_index(typeid(arr)) == std::type_index(typeid(testArr))) << "\n";
std::cout << (std::type_index(typeid(anotherTestArr)) == std::type_index(typeid(testArr))) << "\n";
std::cout << (std::type_index(typeid(yetAnotherTestArr)) == std::type_index(typeid(testArr))) << "\n";
}
This does not have any direct use for you, but it is of great educational value. It will print:
0
1
0
This example demonstrates that arrays of different sizes are different types, and pointers are different types from all array types.
testArr is not a pointer, it is an array with 3 elements.
arr is a pointer - there is not enough knowledge to make begin and end work, because the compiler does not know that it's pointing to an array (and what the size of the hypothetical array is).
My suggestion is: use either std::array or std::vector, depending on what you need to do. If you want to use old-school arrays, change printArrLen to take an array reference:
template <size_t N>
void printArrLen(int (&arr)[N]) {
/* ... */
}
wandbox example

Why does dereferencing an array or not result in the same address?

In C++, I wrote the following simple main:
int main() {
char test[100];
void* a = (void*) test;
void* b = (void*) &test;
std::cout << a << " " << b << std::endl;
return 0;
}
And it gives me the same result for a and b. Why is this? I would expect from the notation that the second be the address of the first..
In C++, arrays are converted to pointer to first element of the array. test is pointer to first element test[0]. &test is the address of entire array test. Although, the type of test and &test are different, their values are same and that's why you are getting the same value.
For example
int a[3] = {5, 4, 6};
Look at the diagram below:
For detailed explanation read this answer.