I have int foo which has the address of an integer in it.
How do I add to the integer that foo is pointing to in one line?
Solution:
(*(int *)foo)+=1
This is how I handled it.
To add to the value the pointer is pointing to:
int * pointer;
int value;
(*pointer) += value; // parans for clarity, not necessarily needed
int a = 4;
int* foo = &a;
// and now the one line you asked
*foo = *foo + 2; // a = 6
If you are incrementing by one and feel like writing it the shortest way (++*pointer). Example:
int i = 0;
int* ip = &i;
cout << i << endl;
++*ip;
cout << i << endl;
Output:
0
1
Related
Ok so I am going to lay out two programs. Both are dynamic arrays using pointers and the new operator. But one doesn't seem to like the delete operator.
#include <iostream>
int main()
{
int *p;
p = new int[5];
for (int i = 0; i < 5; i++)
{
p[i] = 25 + (i * 10);
std::cout << p[i] << " ";
}
std::cout << std::endl;
delete [] p;
p = NULL;
return 0;
}
That's the first program. It likes the delete operator just fine. Now the program that dislikes the delete operator:
#include <iostream>
int main()
{
int x;
int *p;
p = new int[5];
*p = 4;
for (int i = 0; i < 5; i++)
{
std::cout << *p << " ";
x = *p;
p++;
*p = x + 1;
}
std::cout << std::endl;
delete [] p;
p = NULL;
return 0;
}
This program compiles just fine. But during execution, it throws an error - free(): invalid pointer: 0xfdb038 .. or whatever the memory address is for that particular execution. So, the question is:
Why can't the delete operator be used in the second case?
I don't want to have memory leak; I don't want the pointer to be dangling.
If I just say p = NULL;, then p = 0, but I believe the pointer is still dangling?, but I'm not sure. Thanks in advance.
Look at this loop in the second piece of code:
for (int i = 0; i < 5; i++)
{
std::cout << *p << " ";
x = *p;
p++;
*p = x + 1; // <--- Here
}
Notice that in this line, you write to the memory address currently pointed at by p. Since you always increment p and then write to it, you end up writing off past the end of the region that you allocated for p. (If we imagine pOrig as a pointer to where p initially points, then this writes to pOrig[1], pOrig[2], pOrig[3], pOrig[4], and pOrig[5], and that last write is past the end of the region). This results in undefined behavior, meaning that literally anything can happen. This is Bad News.
Additionally, delete[] assumes that you are passing in a pointer to the very first element of the array that you allocated. Since you've incremented p so many times in that loop, you're trying to delete[] a pointer that wasn't at the base of the allocated array, hence the issue.
To fix this, don't write to p after incrementing it, and store a pointer to the original array allocated with new[] so that you can free that rather than the modified pointer p.
You have to delete the pointer that you got from new. However, in your second code you did p++ which changed the pointer. Therefore you tried to delete a pointer you didn't get from new and delete crashes.
To fix this type of error never use new. Instead use std::vector<int> p;. Since you never need new you cannot forget a delete.
Problem is changing p in p++.
You should always store (to delete) original pointer. Like this:
#include <iostream>
int main()
{
int *original = new int[5];
int *p = original;
for (int i = 0; i < 5; i++)
{
std::cout << *p << " ";
int x = *p;
p++;
*p = x + 1;
}
std::cout << std::endl;
delete [] original;
return 0;
}
Suppose that we have these two situations?
int p = 10;
int& q = p;
and
int p = 10;
int q = p;
Are not these two situations the same? I am little confused with the purpose of references, so please explain difference in these two.
int p = 10;
int& q = p;
In this case, q is for all practical purposes an alias for p. They share a memory location. If you modify q, you modify p. If you modify p, you modify q. q is just a different name for p.
int p = 10;
int q = p;
Here, q gets a copy of the value of p at the time when q is initialized. Afterwards, q and p are completely independent. Changing q does not affect p and changing p does not affect q.
In the second case, if you change the value of q it will not affect the value of p. In the first case, changing the value of q will also change the value of p and vice versa.
$ cat ref.cpp
#include <iostream>
int main () {
int p = 10;
int q = p;
int s = 10;
int& t = s;
q = 11;
t = 11;
std::cout << p << std::endl;
std::cout << q << std::endl;
std::cout << s << std::endl;
std::cout << t << std::endl;
s = 12;
std::cout << s << std::endl;
std::cout << t << std::endl;
}
$ g++ ref.cpp
$ ./a.out
10
11
11
11
12
12
$
In Second case p q are two independent integers. in first case both p q will point to same location in the memory. as you asked for the purpose of references. please go through call by value & call by reference. you can understand the use of references. go through the page. http://www.tutorialspoint.com/cplusplus/cpp_function_call_by_reference.htm
Changing a reference will change the underlying variable. This can be useful
in situations like:
int count_odd = 0;
int count_even = 0;
int i;
....
// Create a reference to either count_odd or count_even.
int& count = (i%1) ? count_odd : count_even;
// Now update the right count;
count++;
This is rather artificial, but it becomes more useful with rather more
complicated situations.
Ok, I know that this is invalid
char char_A = 'A';
const char * myPtr = &char_A;
*myPtr = 'J'; // error - can't change value of *myP
[Because we declared a pointer to a constant character]
Why is this valid?
const char *linuxDistro[6]={ "Debian", "Ubuntu", "OpenSuse", "Fedora", "Linux Mint", "Mandriva"};
for ( int i=0; i < 6; i++)
cout << *(linuxDistro+i)<< endl;
*linuxDistro="WhyCanIchangeThis";// should result in an error but doesnt ?
for ( int i=0; i < 6; i++)
cout << *(linuxDistro+i)<< endl;
Thanks for looking!
You write
*linuxDistro = "WhyCanIchangeThis";
which is perfectly valid, because the declaration of linuxDistro was
const char *linuxDistro[6];
i. e. it's an array of 6 pointers to const char. That is, you can change the pointers themselves, just not the characters pointed to by those pointers. I. e., you can not compile
*linuxDistro[0] = 'B';
to obtain the string "Bebian", becuse the strings contain constant characters...
What you probably want is an array of constant pointers to constant characters:
const char *const linuxDistro[6];
*linuxDistro is still a pointer, it is linuxDistro[0], *linuxDistro="WhyCanIchangeThis" it just change the pointer to point to a new address, not to modify the content in the old address, so it is OK.
If you write **linuxDistro='a', it should error.
because the pointer is a variable that stores a memory address, if a pointer is const the pointer keeps storing the same memory address, so the value of the pointer itself can't change, but you are saying nothing about the value pointed by the pointer, according to what you have, chaging the pointed value it's an allowed operation.
because char is not char[], so when you access to * of char[] you access the first element of it (Debian).
when you shift pointer (e.g. +1 it) you access next element of array
here is good example for better understanding
#include <iostream>
using namespace std;
int main ()
{
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << ", ";
return 0;
}
this will output:
10, 20, 30, 40, 50,
int x = 4;
int* q = &x; // Is it always equivalent to int *q = &x; ?
cout << "q = " << q << endl; // output: q = 0xbfdded70
int i = *q; // A
int j = *(int*)q; // B, when is this necessary?
cout << "i = " << i << endl; // output: i = 4
cout << "j = " << j << endl; // output: j = 4
My question is what does lines A and B do, and why the outputs are both 4?
It is a basic usage of pointers, in A you dereference pointer (access the variable to which a pointer points)":
int i = *q; // A
while B is doing exactly the same but it additionally casts pointer to the same type. You could write it like that:
int j = *q; // B
there is no need for (int*)
int x = 4;
x is 4
int* q = &x;
q is the memory location of x (which holds 4)
cout << "q = " << q << endl; // output: q = 0xbfdded70
There's your memory location.
int i = *q; // A
i is the value at memory location q
int j = *(int*)q; // B
j is the value at memory location q. q is being cast to an int pointer, but that's what it already is.
int i = *q; // A
Dereferences a pointer to get the pointed value
int j = *(int*)q; // B
type casts the pointer to an int * and then dereferences it.
Both are same because the pointer is already pointing to an int. So typecasting to int * in second case is not needed at all.
Further derefenecing yields the pointed integer variable value in both cases.
Lines A and B are equivelent as q is already an int* and therefor (int*)q equals q.
int i = *q; yelds that i becomes the value of the integer pointed to by q. If you want to make i to be equal to the adress itself remove the asterisk.
A: Dereference - takes a pointer to a value (variable or object) and returns the value
B: Cast to int* and than dereference
The result is the same because the pointer is already to int. That's it.
Line A takes the value that q points to and assigns it to i. Line b casts q to the type int* (which is q's type already, so that cast is entirely redundant/pointless), then takes the value that q points to and assigns it to j.
Both give you 4 because that's the value that q points to.
Line A de-reference pointer q typed as int *, i.e. a pointer points to an int value.
Line B cast q as (int *) before de-reference, so line B is the same as int j = *q;.
Given a pointer to int, how can I obtain the actual int?
I don't know if this is possible or not, but can someone please advise me?
Use the * on pointers to get the variable pointed (dereferencing).
int val = 42;
int* pVal = &val;
int k = *pVal; // k == 42
If your pointer points to an array, then dereferencing will give you the first element of the array.
If you want the "value" of the pointer, that is the actual memory address the pointer contains, then cast it (but it's generally not a good idea) :
int pValValue = reinterpret_cast<int>( pVal );
If you need to get the value pointed-to by the pointer, then that's not conversion. You simply dereference the pointer and pull out the data:
int* p = get_int_ptr();
int val = *p;
But if you really need to convert the pointer to an int, then you need to cast. If you think this is what you want, think again. It's probably not. If you wrote code that requires this construct, then you need to think about a redesign, because this is patently unsafe. Nevertheless:
int* p = get_int_ptr();
int val = reinterpret_cast<int>(p);
I'm not 100% sure if I understand what you want:
int a=5; // a holds 5
int* ptr_a = &a; // pointing to variable a (that is holding 5)
int b = *ptr_a; // means: declare an int b and set b's
// value to the value that is held by the cell ptr_a points to
int ptr_v = (int)ptr_a; // means: take the contents of ptr_a (i.e. an adress) and
// interpret it as an integer
Hope this helps.
use the dereference operator * e.g
void do_something(int *j) {
int k = *j; //assign the value j is pointing to , to k
...
}
You should differentiate strictly what you want: cast or dereference?
int x = 5;
int* p = &x; // pointer points to a location.
int a = *p; // dereference, a == 5
int b = (int)p; //cast, b == ...some big number, which is the memory location where x is stored.
You can still assign int directly to a pointer, just don't dereference it unless you really know what you're doing.
int* p = (int*) 5;
int a = *p; // crash/segfault, you are not authorized to read that mem location.
int b = (int)p; // now b==5
You can do without the explicit casts (int), (int*), but you will most likely get compiler warnings.
Use * to dereference the pointer:
int* pointer = ...//initialize the pointer with a valid address
int value = *pointer; //either read the value at that address
*pointer = value;//or write the new value
int Array[10];
int *ptr6 = &Array[6];
int *ptr0 = &Array[0];
uintptr_t int_adress_6 = reinterpret_cast<uintptr_t> (ptr6);
uintptr_t int_adress_0 = reinterpret_cast<uintptr_t> (ptr0);
cout << "difference of casted addrs = " << int_adress_6 - int_adress_0 << endl; //24 bits
cout << "difference in integer = " << ptr6 - ptr0 << endl; //6