changing pointers(increasing , decreasing)? - c++

the program below shows *q=46 but q points to an address that is not defined because it points to : p-1 so its not pointing to p or m but another address(because of -1)
then how can it be *q=46
i think it must have a garbage number based on what ive learnt
i hope you get what im trying to say because im not native speaker
int m = 44;
int* p = &m;
int& r = m;
int n = (*p++);
int* q = p – 1;
r = *(--p) + 1;
++*q;
the exercise wants the amount of each variable and pointer and reference above once the program is run
i tested it with a program
output:
p=0022fa00
*p=46
&p=0022f9f4
&n=0022f9dc
n=44
m=46
q=0022fa00 <<<<<<<
r=46
*q=46 <<<<<<<
&m=0022fa00
i thought maybe it's because of int n=(*p++) but i think that shouldnt be the reason because that statement must increment the number in p not the address

int m = 44;//m=44
int* p = &m;//p has address of m *p=44
int& r = m;// r is allias(nickname) of m (*p m r is same)=44
int n = (*p++);//n=44 *p=garbage m=44 r=44 p is m's address+1
// *p++ means give *p then increase p(not *p)
int* q = p - 1;//q shows m's address *q=44
r = *(--p) + 1;//*(--p) means m r= m+1=45 r=45 m=45 because r is allias of m *q=45
++*q;//increase r=46 m=46 (*q)=46
It is what happens at there.I hope this will help.

i thought maybe it's because of int n=(*p++) but i think that shouldnt be the reason because that statement must increment the number in p not the address
Nope. *p++ is *(p++), not (*p)++.

Related

pointer to a variable is not updating variable when dereferenced

This is a debugging problem I've been trying to solve. I know the bit mask I need to apply to make b equal a. I inspected with gdb to find the difference between a and b. The variables b and a are char[] types and set prior to reaching the 'bug'.
#include <string.h>
int main() {
char a[1] = "a";
char b[1] = "b";
int *x;
x = (int *) b;
// bug in next line
*x = *x & 0xffffffff;
return memcmp(a, b, 1);
}
Until a equals b, I can't solve the problem. The only constraint given is that the bug is in the line noted, no other code is to be changed. There is no rule saying I can't add lines after the bug, though and before the memcmp().The issue I find is that nothing I do to the bit mask changes the value of b, ever. I've set breakpoints and inspected the value of x and *x before and after the bug, but x seems to not change.
Breakpoint 1, main () at test.c:9
9 *x = *x & 0xffffffff;
(gdb) print (int) a
$1 = -6922
(gdb) print (int) b
$2 = -6921
(gdb) print (int) x
$3 = -6921
(gdb) step
Breakpoint 2, main () at test.c:10
10 return memcmp(a, b, 1);
(gdb) print (int) a
$4 = -6922
(gdb) print (int) b
$5 = -6921
(gdb) print (int) x
$6 = -6921
I don't see how this can be solved the way requested, by modifying the constant in the line where the bug is. Any help to understand how to use x to update b using a bitwise mask would be appreciated.
x is a pointer; casting it to an int simply gives you the address as a decimal number.
a and b are both arrays, which will decay to a pointer when you do operations that require a pointer. By casting them to int you're again getting the address of the variable. The address doesn't change with the operation you're performing, even when the contents at that address changes.
Since a and b are both smaller than an int, your code is likely to mess up in ways that are extremely painful. Even if they were the right size, this isn't guaranteed to do the right thing.
You are trying to change the address of b but in
*x = *x & 0xffffffff;
You are changing the value because you are dereferencing x. Yyou need to apply the manipulation to x itself like
x = x & 0xffffffff;
And then you need to reassign x into b.
This will run afoul of the strict aliasing rules.

error: cannot increment value of type 'char [6]' [duplicate]

This question already has answers here:
What happens if I increment an array variable?
(5 answers)
Closed 7 years ago.
I am trying to learn pointers and string literals in C/C++.
As per my understanding, string literals are char arrays with a null \0 at the end. Also we can basically do all the pointer arithmetic operations on array like increment and decrement.
But when I am trying to run the following code:
#include <iostream>
using namespace std;
int main (){
char *c ="Hello";
char d[6];
while(*d++ = *c++);
cout<<c<<endl<<d;
}
I am getting the following error,
error: cannot increment value of type 'char [6]'
while(*d++ = *c++);
My assumption for this code was, that the values of string literal c will be copied to char array d.
Edit:
Now I am a bit confused about the difference between these 2 statements:
*(d++)
and
*(d+1)
assuming d is an array.
char d[6];
while(*d++ = *c++);
Should be Re-written to:
char d[6];
int idx = 0;
while(d[idx++] = *c++);
Because in char d[6];, d is an array (not to be confused with pointer) and you can not change the address of an array. On the other hand, type of c is char * so you can modify it.
c++; // OK
c = &d[0]; // OK
d++; // Not allowed
d = c; // Not allowed
About your added question:
Difference between: *(d++) and *(d+1)
Consider following example:
int index1 = 42, index2 = 42;
int j = index1++; // j = 42 and index1 = 43
int k = (index2 + 1); // k = 43 and index2 = 42 (unchanged)
Similarly when you write *(d++), you are trying to access (by dereferencing) the current location and then increment the pointer itself to next location. But when you write *(d + 1), you are accessing the next location and the pointer itself remains unchanged.
If the d pointer is constant or is an array first form (where d is changed) is not allowed but the second form (where the pointer itself remains unchanged) is allowed.
Array name can't be a modifiable lvalue
so
d++
can be written as
d = d+1;
So there is an error which should be fixed as
while(d[index++] = *c++);

Can I work on the 4 int32_t contained in a __m128i?

I would like to have a __m128i variable,
and do some operation like this:
unsigned char* myArray;
__m128i fourValues;
//Do some strange reference assignment, e.g.:
//int32_t& a = *((int32_t*) &fourValues);
//int32_t& b = *(((int32_t*) &fourValues) + 1);
//int32_t& c = *(((int32_t*) &fourValues) + 2);
//int32_t& d = *(((int32_t*) &fourValues) + 3);
for (int i =0; i < someSize; i+=4) {
a = d + myArray[i];
b = a + myArray[i+1];
c = b + myArray[i+2];
d = c + myArray[i+3];
//Do something with fourValues;
}
where a,b,c,d are (or behave as) int32_t variables, and are the first, second, third and fourth 32bits of fourValues. Is that possible?
You can use
int _mm_extract_epi32(
__m128i a,
const int ndx
);
see -
http://msdn.microsoft.com/en-us/library/bb531460%28v=vs.90%29.aspx
EDIT: Note that this only works for int SSE vectors, I see there's quite a lot of debate going around here - Get member of __m128 by index? , which refers to a __m128, but in your case it should be possible to use that. Still, always worth to get a heads up that this isn't generic enough for floats.
For writing you can use the equivalient _mm_insert_epi32, as you point out.

Compiler Behavior for Integer pointers to undeclared memory

What is the value of q after the following code executes?
m' is stored in memory starting at byte 2 and no problems with memory.
int m = 44;
int* p = &m;
int n = (*p)++;
int* q = p - 1;
++*q;
When I execute this code on gcc, the code initializes the memory pointed to by q to 1606417464 and then the last line changes it to 1606417465. This makes sense to me as this block of memory has not been assigned a value.
When I execute this code on my mac using xtools, the memory pointed to by q is initialized as zero and then changes to 1 after ++*q. Any idea why this behavior occurs?
Your code invokes undefined behaviour when you try to modify *q (as in ++*q).
int m = 44; // Let's say &m is 1000.
int* p = &m; // p is 1000 now.
int n = (*p)++; // assigns 45 to 'n'.
// Now *p (which is 'm') becomes 45.
// Note p is not modified here but only *p is modified.
int* q = p - 1; // q is 996 or 1004 (depending on which side stack grows)
// and assumes sizeof(int*) == 4
// which may or may not a valid address and may not belong
// to your program.
++*q; // Here you are essentially modifying some random memory.

Pointer Arithmetic? What is the difference between these three expressions?

So I am trying to understand two things:
What are the differences between these three expressions?
What is the equivalent to the first expression (A)?
Here is the code (fixed):
#include "stdafx.h"
void someFunc(double** pArray, int length)
{
for(int i = 0; i < length; i++)
{
//this works perfectly
double expressionA = *(*pArray + i);
//this crashes : Unhandled exception at 0x00da13ff in pptrtest.exe: 0xC0000005: Access violation reading location 0xcccccccc.
double expressionB = **(pArray + i);
//this crashes : Unhandled exception at 0x00da13ff in pptrtest.exe: 0xC0000005: Access violation reading location 0xcccccccc.
double expressionC = *pArray[i];
}
}
int main()
{
double arr[] = { 1, 2, 3, 4, 5 };
double* pArr = arr;
someFunc(&pArr, sizeof arr / sizeof arr[0]);
return 0;
}
I think the problem is, that [] is applied before *, so in expr C you are doing
*(ppDoubleArray[i])
actually the equivalent of expr B, but the expr A does
(*ppDoubleArray)[i]
(assuming the 1 in the expression should be an i, otherwise thats different anyway).
You have a pointer to a pointer of double. Think of it as a pointer to an array of doubles. Either ways, the following is their meanings:
double expressionA = *(*ppDoubleArray + 1); is the same as: double expressionA = *((*ppDoubleArray) + 1);
double expressionB = **(ppDoubleArray + 1); is the same as: double expressionB = *(*(ppDoubleArray + 1)); which means you want to de-reference ppDoubleArray[1] which am guessing doesn't exist.
double expressionC = *ppDoubleArray[i]; is the same as: double expressionC = *(ppDoubleArray[i]); -- again, you are de-referencing ppDoubleArray[i] which does not exist.
Like everyone else said, you need to be mindful of the order of preference. Basically, dereference first then index your array.
double expressionB = **(ppDoubleArray + 1);
Lets look at memory for this guy, on the stack you've got a pointer to a pointer to a double. So if its an address in memory for a 32-bit processor, the stack could look something like:
stack: |ppDoubleArray ptr |local vars, other args, or garbage |more locals/etc
addr: |0 bytes from stack |4 bytes from stack |8bytes...
So when we look at the first part of the expression
(ppDoubleArray + 1)
This says "go one pointer past ppDoubleArray". Go to the next pointer by going to the next spot in memory. What is the next spot in memory past ppDoubleArray? Look at the stack above, its probably some local variables or the other argument. So now you have who knows what (maybe the contents of length? one of the doubles? garbage?) and you're going to treat it as if it were a valid address somewhere. You then follow that supposed pointer, by dereferencing:
**(ppDoubleArray + 1)
And crash!
So, for example, if length was 5, ppDoubleArray+1 might grab 5 and dereference "5" looking for something at that address.
This code:
double expressionC = *ppDoubleArray[i];
works the same way, the [] take precedence over the dereference. So you go to the ith memory location past ppDoubleArray and assume its pointing at your array.
Rearranging the order of operations with parent would, however work:
(*ppDoubleArray)[i]
Assuming ppDoubleArray is a pointer to an array of doubles:
The second one crashes because you are adding one to the pointer to the array not selecting the correct index from it.
The third one crashes because of the precedence of the operators. you are selecting the ith element which is not the array (unless i is 0) and then dereferencing that.
The important thing to remember here is how to deal with a pointer to an array (or a pointer to a pointer) You dereference it once to get to the array, at which point you can do the arithmetic and then dereference it again to get to the element.
aSCII art Time:
---> = derefering
double expressionA = *(*ppDoubleArray + 1);
ppDoubleArray ---> .
+1
. ---> expressionA
double expressionB = **(ppDoubleArray + 1);
ppDoubleArray
+1
. ---> . ---> expressionB
double expressionC = *ppDoubleArray[i];
ppDoubleArray
+i
. ---> . ---> expressionC