i am learning c++ and i find this bit confusing about the pointers . is it allowed or is it possible to modify the variable int a using pointer variable ?
here's the code :
#include <iostream>
int main(){
int a ; // int variable
int *p ; // pointer
a = 10 ;
*p =15 ;
std:: cout << a ;
return 0;
};
does *p = 15 change the value of a ?
i got error when i tried to run the code :
zsh: bus error
There's no relationship between p and a. p points to invalid memory, and dereferencing or assigning to it is undefined behavior.
If you want modifications to p to affect a, you need to set where it points to.
int a;
int *p = &a;
Silvio's answer is correct.
Bus errors occur when your processor cannot even attempt the memory access requested.
This usually happens when using a processor instruction with an address that does not satisfy its alignment requirements.
you can read more about this here.
You need to assign the address of variable a to the pointer p.
p = &a;
Now, if you will change the value of the pointer to 15 it will be reflected in the variable a. And you won't get an error.
Related
What is the difference between int* i and int** i?
Pointer to an integer value
int* i
Pointer to a pointer to an integer value
int** i
(Ie, in the second case you will require two dereferrences to access the integer's value)
int* i : i is a pointer to a object of type int
int** i : i is a pointer to a pointer to a object of type int
int*** i : i is a pointer to a pointer to a pointer to object of type int
int**** i : i is a pointer to a pointer to a pointer to a pointer to object of type int
...
int* pi
pi is a pointer to an integer
int **ppi
ppi is a pointer to a pointer to an integer.
EDIT :
You need to read a good book on pointers. I recommend Pointers on C by Kenneth Reek.
Let's say you're a teacher and have to give notes to one of your students.
int note;
Well ... I meant the whole class
int *class_note; /* class_note[0]: note for Adam; class_note[1]: note for Brian; ... */
Well ... don't forget you have several classes
int **classes_notes; /* classes_notes[0][2]: note for Charles in class 0; ... */
And, you also teach at several institutions
int ***intitute_note; /* institute_note[1][1][1]: note for David in class 1 of institute 1 */
etc, etc ...
I don't think this is specific to opencv.
int *i is declaring a pointer to an int. So i stores a memory address, and C is expecting the contents of that memory address to contain an int.
int **i is declaring a pointer to... a pointer. To an int. So i contains an address, and at that memory address, C is expecting to see another pointer. That second memory address, then, is expected to hold an int.
Do note that, while you are declaring a pointer to an int, the actual int is not allocated. So it is valid to say int *i = 23, which is saying "I have a variable and I want it to point to memory address 23 which will contain an int." But if you tried to actually read or write to memory address 23, you would probably segfault, since your program doesn't "own" that chunk of RAM. *i = 100 would segfault. (The solution is to use malloc(). Or you can make it point to an existing variable, as in int j = 5; int *i = &j)
Imagine you have a few friends, one of them has to give you something (a treasure... :-)
Say john has the treasure
int treasure = 10000; // in USD, EUR or even better, in SO rep points
If you ask directly john
int john = treasure;
int you = john;
If you cannot join john, but gill knows how to contact him,
int john = treasure;
int *gill = &john;
int you = *gill;
If you cannot even join gill, but have to contact first jake who can contact gill
int john = treasure;
int *gill = &john;
int **jake = &gill;
int you = **jake;
Etc... Pointers are only indirections.
That was my last story for today before going to bed :-)
I deeply believe that a picture is worth a thousand words. Take the following example
// Finds the first integer "I" in the sequence of N integers pointed to by "A" .
// If an integer is found, the pointer pointed to by P is set to point to
// that integer.
void f(int N, int *A, int I, int **P) {
for(int i = 0; i < N; i++)
if(A[i] == I) {
// Set the pointer pointed to by P to point to the ith integer.
*P = &A[i];
return;
}
}
So in the above, A points to the first integer in the sequence of N integers. And P points to a pointer that the caller will have the pointer to the found integer stored in.
int Is[] = { 1, 2, 3 };
int *P;
f(3, &Is[0], 2, &P);
assert(*P == 2);
&P is used to pass the address of P to the function. This address has type int **, because it's the address of a pointer to int.
int* i is the address of a memory location of an integer
int** is the address of a memory location of an address of a memory location of an integer
int* i; // i is a pointer to integer. It can hold the address of a integer variable.
int** i; // i is a pointer to pointer to integer. It can hold address of a integer pointer variable.
Neither is a declaration. Declaration syntax does not allow () around the entire declaration. What are these () doing there? If this is supposed to be a part of function declaration, include the whole function declaration thing in your question, since in general case the actual meaning of a declaration might depend on that. (Not in this one though.)
As for the difference... There is one * in the first and there are two *s in the second. Does it help? Probably not. The first one declares ias a pointer to int. The second one declares i as a pointer to int *. Does this help? Probably not much either. Without a more specific question, it is hard to provide a more meaningful answer.
Provide more context, please. Or, if this is actually as specific as it can get, read your favorite C or C++ book about pointers. Such broad generic questions is not something you ask on the net.
Note that
int *i
is not fully interchangeable with
int i[]
This can be seen in that the following will compile:
int *i = new int[5];
while this will not:
int i[] = new int[5];
For the second, you have to give it a constructor list:
int i[] = {5,2,1,6,3};
You also get some checking with the [] form:
int *i = new int[5];
int *j = &(i[1]);
delete j;
compiles warning free, while:
int i[] = {0,1,2,3,4};
int j[] = {i[1]};
delete j;
will give the warnings:
warning C4156: deletion of an array expression without using the array form of 'delete'; array form substituted
warning C4154: deletion of an array expression; conversion to pointer supplied
Both of these last two examples will crash the application, but the second version (using the [] declaration type) will give a warning that you're shooting yourself in the foot.
(Win32 console C++ project, Visual studio 2010)
Textual substitution is useful here, but beware of using it blindly as it can mislead you (as in the advanced example below).
T var; // var has type T
T* var; // var has type "pointer to T"
This works no matter what T is:
int* var; // pointer to int
char* var; // pointer to char
double* var; // pointer to double
// advanced (and not pure textual substitution):
typedef int int3[3]; // confusing: int3 has type "array (of size 3) of ints"
// also known as "int[3]"
int3* var; // pointer to "array (of size 3) of ints"
// aka "pointer to int[3]"
int (*var)[3]; // same as above, note how the array type from the typedef
// gets "unwrapped" around the declaration, using parens
// because [] has higher precedence than *
// ("int* var[3];" is an array (size 3) of pointers to int)
This works when T is itself a pointer type:
typedef int* T; // T is a synonym for "pointer to int"
T* var; // pointer to T
// which means pointer to pointer to int
// same as:
int** var;
When I tried below code I got strange results.I am trying to change value of constant by using the pointers.But when I output the results pointer value and the original variable variable value its giving two different values.Can anyone explain what exactly happens when explicit conversion take place?
int main()
{
int *p ;
const int a = 20;
p=(int *)&a;
*p = *p +10;
cout<<"p is"<<*p<<"\na is"<<a;
}
output:
p is 30
a is 20
Both C and C++ say that any attempt to modify an object declared with the const qualifier results in undefined behavior.
So as a is object is const qualified, the *p = *p +10; statement invokes undefined behavior.
First of - You really shouldn't be doing this. const is a constant, meaning don't change it! :)
Now to explain what happens (I think):
The space on the stack is allocated for both variables, p and a. This is done for a because it has been referenced by an address. If you removed p, you'd effectively remove a as well.
The number 20 is indeed written to the a variable, and modified to 30 via p, which is what is being printed.
The 20 printed is calculated at compile time. Since it is a const, the compiler optimized it away and replaced with 20, as if you did a #define a 20.
Don't Do That.
If you would write this code in C++ with an explicit cast, you would get something like this:
int main()
{
int *p ;
const int a = 20;
p= const_cast<int*>(&a); // the change
*p = *p +10;
cout<<"p is"<<*p<<"\na is"<<a;
}
Now, this code tells a bit more about what's going on: the constant is cast to a non-constant.
If you are writing a compiler, constants are special variables that are allowed to be 'folded' in the const folding phase. Basically this means that the compiler is allowed to change your code into this:
int main()
{
int *p ;
const int a = 20;
p= const_cast<int*>(&a);
*p = *p +10;
cout<<"p is"<<*p<<"\na is" << 20; // const fold
}
Because you're also using &a, you tell the compiler to put the value 20 in a memory location. Combined with the above, you get the exact results you describe.
This is undefined behavior.
A compiler can assume that nothing is going to change the value of a const object. The compiler knows that the value of "a" is 20. You told the compiler that. So, the compiler actually goes ahead and simply compiles the equivalent of
cout << "p is" << *p << "\na is" << 20;
Your compiler should've also given you a big fat warning, about "casting away const-ness", or something along the same lines, when it tried to compile your code.
Although it is defined as undefined behaviour (as everyone else tells you), it could be that your compiler has allocated a storage location (int) for the const int; that is why the *p= *p + 10 works, but may have repaced a in the output statement with the value 20, as it is supposed to be constant.
I'm a programming and c++ novice. I'd appreciate some help with this.
the following program (in c++) doesn't encounter any problem either in compilation or run-time:
int main()
{
int b = 5;
int*a = &b;
*(a+5) = 6;
return 0;
}
But according to everything I learned it shouldn't work, because a is a pointer to a single variable. What am I missing here?
Your program should indeed not encounter any problem at compile time. It is all valid code with regards to compilation.
However it will encounter undefined behaviour at runtime as a+5 is not a valid address.
If you want to know why it should compile, you can write code like this:
int func( int * buf, size_t size )
{
for( size_t i = 0; i < size; ++i )
{
*(buf + size) = static_cast<int>(i); // or (int)i in C
}
}
int main()
{
int buf[ 6 ];
func( buf, 6 );
}
In your code a is a pointer to memory. a + 5 means an address 5 "ints" on from where a points. As a was pointed at a single integer b, there are no guarantees about such an address. Interestingly enough, it is well defined to refer to a+1 even though it points to a place in memory that you should not read from or write to. But the pointer itself has some guarantees, i.e. it will be greater than a and if you subtract 1 from it you will get back to a and if you do a ptrdiff between it and a you will get 1. But that is just a special property of "one past the end" which allows programmers to specify memory ranges.
The program do have an undefined behaviour:
int main()
{
//This cause the loading of the "main" function to allocate memory for variable b
//It could be in a memory page that was already allocated to the program
//or in a new allocated page.
int b = 5;
//Here a just getting the address of variable b.
int*a = &b;
//This is the undefined behavior and can end up in two cases:
// 1. If (a+5) value is in a memory space that is allocated to the application.
// Then no runtime error will happen, and the value will be writing there.
// probably dirting some other value, and can cause an undefined behavior later
// in the application execution.
// 2. If (a+5) value is in a memory space that wasn't allocated to the application.
// the application will crash
*(a+5) = 6;
return 0;
}
Now, since a page size is probably 4096 and b is somewhere within a page, *b+5 is in most cases still be in the same page. If you want to challenge it more change it from 5 to 5000 or higher and the chance for crashes will increase.
Yes it shouldn't work when you access memory space which is not in your process region, but perhaps no one has owned that particular region ((a + 5)) which didn't cause run time illegal memory access or it can. Hence its a UB.
Just adding to the existing answers.
The access
*(a+5) = a[5]
So this is the location not allocated by you.
In the case of array say
int a[6];
You have a valid access from a[0] to a[5] where a[5] is the last element of the array and any further access like a[6] will lead to undefined behavior as that location is not allocated by you.
Similarly you just have a integer allocated like
int b=5;
int *a = &b;
a is a pointer pointing to &b i.e address of b.
So the valid access for this is just a[0] which is the only location allocated by you on the stack.
Any other access like a[1] a[2]... and so on will lead to undefined behavior.
The access turns out to be VALID if you have something like
int b[6];
int *a = b;
Now a[5] will give the value of the last element of the array b
I have a method which fills the array with integers:
void fill(int* a[], int dim1, int dim2)
{
int intinArray = 0;
for(int i=0;i<dim1;i++)
{
for(int j=0;j<dim2;j++)
{
cin >> intinArray;
a[i][j] = intinArray;
}
}
}
If I declare array in method main() like this:
int** tab;
fill(tab,3,3);
It crashes when I put the first integer in cin. Why? If there's a problem with this line:
a[i][j] = intinArray;
how should I change it?
The fundamental thing wrong with your code is that you declared pointers, but nowhere do you initialize the pointers to point somewhere. You treat the pointer as if it is a regular old 2 dimensional array of integer. So if it's as easy as that, why use pointers?
Given that this is a fundamental in pointer usage and you plainly aren't doing that, the solution is to review working code that uses pointer.
int main()
{
int *p; // uninitialized -- points to who-knows-where
*p = 10; // this is undefined behavior and may crash
}
Take that code and understand why it also may crash. That pointer points to "we don't know", and then you're assigning 10 to a location that is unknown to you, me, and everyone else reading this answer. See the problem? To fix it, you have to initialize the pointer to point somewhere valid, then you can dereference it and assign to it without error.
int main()
{
int *p; // uninitialized -- points to who-knows-where
int x = 20;
p = &x; // this is now ok, since p points to x
*p = 20; // now x changes to 20
}
Your problem is in this code
int** tab; // <- this one
fill(tab,3,3);
You declared a pointer, and are using it under the assumption that it is pointing to allocated memory. (I guess a source of confusion is that with C++ objects this isn't really the case)
A pointer is a pointer - it points to a location in memory. There's no guarantee that the value it points to is valid unless you explicitly make sure it is yourself.
Read PaulMcKenzie's answer for more about pointers.
Try
int tab[x][y] = {{0}};
fill(tab,3,3);
where x and y define your 2D array's width and height. You're going to have to handle bounds checking for your application.
Note that changing {{0}} to a non zero number will not initialize everything to that number.
Please Explain the following code
#include <iostream>
using namespace std;
int main()
{
const int x = 10;
int * ptr;
ptr = (int *)( &x ); //make the pointer to constant int*
*ptr = 8; //change the value of the constant using the pointer.
//here is the real surprising part
cout<<"x: "<<x<<endl; //prints 10, means value is not changed
cout<<"*ptr: "<<*ptr<<endl; //prints 8, means value is changed
cout<<"ptr: "<<(int)ptr<<endl; //prints some address lets say 0xfadc02
cout<<"&x: "<<(int)&x<<endl; //prints the same address, i.e. 0xfadc02
//This means that x resides at the same location ptr points to yet
//two different values are printed, I cant understand this.
return 0;
}
*ptr = 8;
This line causes undefined behavior because you are modifying the value of a const qualified object. Once you have undefined behavior anything can happen and it is not possible to reason about the behaviour of the program.
Since x is a const int, the compiler will most likely, in the places where you use x, directly substitute the value that you've initialized with (where possible). So the line in your source code:
cout<<"x: "<<x<<endl;
will be replaced by this at compile time:
cout<<"x: "<<10<<endl;
That's why you still see 10 printed.
But as Charles explained, the behaviour is undefined, so anything could happen with code like this.