#include <iostream>
int main() {
int a[2][2] = {{1,2}, {3,4}};
int *c = *a;
int **b = &c;
std::cout << **(a+1); // outputs 3
std::cout << **(b+1); // segmentation fault
}
Why does one cout results in segmentation fault and other doesn't? Shouldn't they be referring to the same value?
Lets start with
int *c;
Actually what comes before is not that relevant, because c is just a pointer and then here
int **b = &c;
you store the address of c in b. The address of c has nothing to do with what value is stored in c. c is just a pointer, taking its adress doesn't let you magically access a 2d array.
cout << **(b+1); // segmentation fault
Already b+1 is undefined behaviour. Dereferencing that pointer cannot give you something meaningful.
PS: tbh I cannot tell you how to use the double pointers correctly here. Once I started to learn c++ I unlearned anything I knew about working with arrays via pointers. Use std::vector or std::array and save yourself some headaces.
In this statement
cout << **(b+1);
the expression b+1 points outside the array (that is more precisely outside the object c). You should write
cout << *( *b + 2 );
The dereferenced pointer b points to the pointer to the first element of the two-dimensional array. When adding to it the number of elements in the array of the type int[2] you will get the pointer to the first element of the second "row" of the two-dimensional array. Now you need again to dereference it to output the pointed value.
I rewrote the code to highlight what is happening, as below:
#include <iostream>
int main() {
int a[2][2] = {{1,2}, {3,4}};
int *c[2] = {a[0], a[1]};
int **b = c;
std::cout << **(a ) << ','; // outputs 1
std::cout << **(b ) << ";\n"; // outputs 1
std::cout << **(a+1) << ','; // outputs 3
std::cout << **(b+1) << ";\n"; // outputs 3
}
LINK: https://ideone.com/ixj3NV
UPDATED LINK: https://ideone.com/g7jjVN
(Clarified the original source to extend the program)
Related
#include <iostream>
int main() {
int b = 3;
int* a;
*a = b;
std::cout << &a << a << *a;
}
When I execute a.out, Segmentation fault occurs
#include <iostream>
int main() {
int b = 3;
int* a;
*a = b;
std::cout << &a << a;
std::cout << *a;
}
While this code runs clearly with no error.
I'm pretty sure that max size of stdout buffer is bigger than couple of characters...
Why am I seeing Segmentation fault in same code with different new line?
Why am I seeing Segmentation fault ...?
Because the behaviour of the program is undefined. Here is the list of bugs in your programs:
*a = b;
^^
indirect through indeterminate pointer
std::cout << &a << a << *a;
^ ^^
| indirect through indeterminate pointer
read an indeterminate value
These bugs affect both example programs.
To fix the bugs, initialise a with a valid address of an int object.
after ptr++ pointer does not increment
1 #include<iostream>
2
3 int main() {
4
5 char *ptr;
6 char ch = 'A';
7 ptr = &ch;
8
9 std::cout << "pointer :" << &ptr << "\n";
10 ptr++;
11 std::cout << "pointer after ++ :" << &ptr << "\n";
12 return 0;
13 }
ikar$ g++ pointer_arth.cpp
ikar$ ./a.out
pointer :0x7ffeed9f19a0
pointer after ++ :0x7ffeed9f19a0
ikar$
You're incrementing the pointer, but outputting the address of the variable that holds the pointer itself (&ptr). You should output just ptr (and format it accordingly - see edit below).
Example:
#include <iostream>
int main() {
char data;
char *ptr = &data;
std::cout << "pointer:" << (unsigned long long)ptr << std::endl;
ptr++;
std::cout << "pointer incremented: " << (unsigned long long)ptr << std::endl;
}
Output:
pointer:140732831185615
pointer incremented: 140732831185616
Yes, printing just ptr will output garbage, so I converted the pointer to an integer (since pointers are memory addresses anyway).
As suggested in the comments, you can cast the pointer to void * when printing, which gives nicer formatting:
pointer:0x7ffee5467acf
pointer incremented: 0x7ffee5467ad0
Note how 0x7ffee5467acf == 140732745022159 != 140732831185615 - you'll get different outputs on each run because the kernel will load the executable into different places in memory.
EDIT: yes, the first version of this answer, about simply outputting ptr with std::cout << ptr, was incorrect, because the << operator is overloaded in such a way that it treats pointers to char as C-strings. Thus, that version would access potentially invalid memory and output garbage.
But the concept remains the same. Pointers to int, for example, don't have this "problem" and are printed as hexadecimal numbers, even without casting them to void *: Try it online!. The output shows that pointers are still incremented correctly by sizeof(int), which equals 4 on that machine.
Pointer is incremented successfully in your code.
You print the address of location which hold the pointer variable.
Actually, it is garbage after character -'A' if print 'ptr', you can understand and pointing to such un-handled memory location is not good.
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
(Disclaimer: Pointers in C++ is a VERY popular topic and so I'm compelled to believe that someone before me has already raised this point. However, I wasn't able to find another reference. Please correct me and feel free to close this thread if I'm wrong.)
I've come across lots of examples that distinguish between pointer to first element of array and pointer to the array itself. Here's one program and its output:
//pointers to arrays
#include <iostream>
using namespace std;
int main() {
int arr[10] = {};
int *p_start = arr;
int (*p_whole)[10] = &arr;
cout << "p_start is " << p_start <<endl;
cout << "P_whole is " << p_whole <<endl;
cout << "Adding 1 to both . . . " <<endl;
p_start += 1;
p_whole += 1;
cout << "p_start is " << p_start <<endl;
cout << "P_whole is " << p_whole <<endl;
return 0;
}
Output:
p_start is 0x7ffc5b5c5470
P_whole is 0x7ffc5b5c5470
Adding 1 to both . . .
p_start is 0x7ffc5b5c5474
P_whole is 0x7ffc5b5c5498
So, as expected, adding 1 to both gives different results. But I'm at a loss to see a practical use for something like p_whole. Once I have the address of the entire array-block, which can be obtained using arr as well, what can I do with such a pointer?
For single arrays, I don't think there's much point to it. Where it becomes useful is with multi-dimensional arrays, which are arrays of arrays. A pointer to one of the sub-arrays is a pointer to the row, and incrementing it gets you a pointer to the next row. In contrast, a pointer to the first element of the inner array is a pointer to a single element, and incrementing it gets you the next element.
int (*)[10] is a "stronger" type than int* as it keeps size of the array,
so you may pass it to function without passing additional size parameter:
void display(const int(*a)[10]) // const int (&a)[10] seems better here
{
for (int e : *a) {
std::cout << " " << e;
}
}
versus
void display(const int* a, std::size_t size) // or const int* end/last
{
for (std::size_t i = 0; i != size; ++i) {
std::cout << " " << a[i];
}
}
I have the following code:
#include <iostream>
using namespace std;
int main ()
{
int myvar = 5;
int * p;
cout << "Hello2" << endl;
*p = myvar;
cout << "Hello" << endl;
cout << p << endl;
//cout << &myvar << endl;
}
I know I am not doing the right thing by not initializing the pointer. I was just playing with pointers and noticed this. The issue is when I comment out the last line, the program executes normally. But as soon as I uncomment the line, I get a segmentation fault. I don't know why printing address of myvar is causing this? Has myvar been modified in any way because of pointer dereferencing? I am using C++11.
int* p;
*p = myvar;
You are creating an uninitialized pointer and then derferencing that pointer. This has undefined behavior because p has to point to something for it to be derferenced correctly. Therefore your program's behavior can't be reasoned with.
Segmentation Fault occurs when trying to access a virtual memory address that has no read permissions.
In your case, the local variable p holds uninitialized garbage from the stack.
you are dereferencing a memory address that might not be readable(e.g no read permissions, hence the segmentation fault when trying to access it).
I'm not entirely sure the purpose of your snippet, but the following code will work, and perhaps it will help:
int myvar = 5;
int *p = nullptr;
p = &myvar;
cout << myvar << endl;
cout << &myvar << endl;
cout << p << endl;
cout << *p << endl;
(Note: I used two lines for setting 'p' because that is how you did it in your snippet. You could easily just use: int *p = &myvar; )
Anyway, there are scope issues here as p will only be valid as long as myvar is in scope; however, this does illustrate the basics of pointers. myvar and *p will return the same value (the value being pointed to), and &myvar and p will return the same value (the location of value in memory.)