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.
Related
I am looking at a unique example here and am trying to understand why his snippet behaves the way it does
// uninitialized mem
char test[99999];
//
test[0] = 'a';
test[1] = 'b';
test[2] = 'c';
test[3] = 'd';
test[4] = 'e';
test[5] = 'f';
test[6] = 'g';
for (int i = 0; i < 99999; i++) {
cout << (&test[i])[i] << endl;
}
In particular, what is happening in memory for the output to skip a character?
output:
a
c
e
g
..
This is what is happening:
An array is just a contiguous chunk of memory.
&test
Is getting the address of that index of the starting point of array. Not the value.
When you add [some number], it counts up the number times the size of the data type, in this case each char is a byte.
So when you do
&test[i]
that means the starting address + i bytes.
when you do
(&test[i])[i]
You are doing i bytes from the starting address, and then treat that as the starting address and go up i more bytes.
So in your iterations:
(&test[0])[0] // index 0 + 0 = 0
(&test[1])[1] // index 1 + 1 = 2
(&test[2])[2] // index 2 + 2 = 4
(&test[3])[3] // index 3 + 3 = 6
It should become a bit more obvious when you consider what the array indexing is actually doing.
Given an array test, you usually access the nth element of test with test[n]. However, this is actually the equivalent of *(test+n). This is because addition on pointers automatically multiplies the amount you add with the size of the type being pointed to. This means the pointer will then be pointing at the second item in the array if you add one to the pointer, the third item if you add two, and so on.
The code you provide then references that value, so you end up with &(*(test+n)). The reference (&) and the dereference (*) operations then cancel each other out, which means you end up with just test+n.
The code then does another array index on that value, so you end up with (test+n)[n], which again may be written as *((test+n)+n). If you simplify that, you get *(test+n+n), which may be rewritten as *(test+2*n).
Clearly then, if you convert that back to array indexing notation, you end up with test[2*n], which indicates in simple form that you'll be querying every other element of the array.
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.
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)++.
Hi i have array of two pointers int *p[2] and i am trying to store 3 address of integer lets take &i,&j,&k as below code At *p[0]
i am getting garbage why here garbage ?it should be at p[2]? At *p[1] i am getting value it is ok but At *p[2] i am getting value here i should get garbage?
#include<stdio.h>
int main()
{
int i=10,j=20,k=30;
int *p[2]; // here p is array of 2 pointers
p[0]=&i; // but here i am storing
p[1]=&j; // 3 address of variable i,j,k
p[2]=&k;
printf("p[0]=%d\n",*p[0]); // why garbage here ?
printf("p[1]=%d\n",*p[1]); // here 20
printf("p[2]=%d\n",*p[2]); // here 30 why here ?
}
printf("p[2]=%d\n",*p[2]); // here 30 why here ?
Because p has two elements, not three. You can access elements 0 and 1, but accessing 2 is undefined behavior. Any number can be printed, or your program could crash when you invoke undefined behavior.
I am getting value here i should get garbage?
30 is as good a garbage value as any other number.
**EDIT (in response to an edit of the question) When you assign p[2] = &k you write to a location that is not allocated to your program. However, if the write operation completes without a crash, the new value would stay in memory.
Since the memory to which you wrote an address of k does not belong to your program, the system may write a new value into it. However, it wouldn't do it with 100% certainty: it may not write a new value into that memory at all. This is precisely what appears to be happening in your case: the value of &k written into p[2] illegally "survives" past two invocations of printf, producing 30 as the result.
u are using int *p[2], which is an array of size 2. only p[0] and p[1] are valid. remember the index of an array in c++ starts with 0 not 1. using p[2] would end up with something strange.
you are having array of two pointers int *p[2]. But you are trying to print the next element using pointer-
printf("p[2]=%d\n",*p[2]);
It results in undefined behavior. Anything can happen. But you are getting 30 some times you may get garbage values.
For your program i am getting-
root#ubuntu:~/c/array/string# ./a.out
p[0]=10
p[1]=20
p[2]=-13543595 // note this value. Undefined Behaviour
root#ubuntu:~/c/array/string#
first of all you need
int *p[3].
secondly since you used
int *p[2]
p[2] wasn't kept aside for this array. so what was there at p[2]? in my case it was variable k.
mine was 64 bit system with 64 bit pointers.
my output
p[0]=10
p[1]=20
p[2]=32767
and look at the gdb dump especially the addresses of k and p[2]
(gdb) p p[0]
$7 = (int *) 0x7fffffffe02c
(gdb) p p[1]
$8 = (int *) 0x7fffffffe028
(gdb) p p[2]
$9 = (int *) 0x7fffffffe024
(gdb) p &i
$10 = (int *) 0x7fffffffe02c
(gdb) p &j
$11 = (int *) 0x7fffffffe028
(gdb) p &k
$12 = (int *) 0x7fffffffe024
(gdb) p &p
$14 = (int *(*)[2]) 0x7fffffffe010
(gdb) x/32 0x7fffffffe010
0x7fffffffe010: -8148 32767 -8152 32767
0x7fffffffe020: -8156 32767 20 10
in your case it must have been the address of i.
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