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.
Related
Got this piece of code from an homework assignment. I should figure out, what the value of &y[0] == &x.a. Btw sorry for not formatting properly, I tried my best.
So my approach was; y[0] = 1, and &y[0] means the address of 1, which is 0 in the array?
x.a confused me the most. Does it mean element a of the struct x? So x.a == 1 ? And its address would also be 0? So the boolean would come out as true(1), because 0 == 0. But the solution says it's false, but why?
struct my_struct {
int a;
double b;
int c;
};
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
I expected the output 1 but apparently it's 0, but why?
&y[0] means the address of 1, which is 0 in the array
Almost, but not quite. The addresses given to you by the address-of operator are absolute values, not ones relative to the "container". So &y[0] is effectively the same as y, and &x.a is effectively the same as &x.
y is a value that can be converted to a pointer to the first element. This must and will be distinct (numerically) from &x which occupies a different part of memory.
| x.a | <- &x points here
| x.b |
| x.c |
| y[0]| <- y points here
| y[1]|
[ y[2]|
All of the above skims over the fact that those pointers might have different types. This matters to the compiler when checking the correctness of your code, but is ultimately discarded afterwards, as all addresses effectively become numerical values.
This expression
&y[0] == &x.a
compares addresses (pointers) of two different objects. The first one belongs to the array y (that is y[0] is the first element of the array) while the second one belongs to an object of the type my_struct (a is a data member of the object x).
The objects occupy different extents of memory.
So the expression yields false that is the addresses of the different objects are not equal each other.
I can provide an example when comparing two different pointers (that is pointers of different types) yields true.
Consider the following example
struct my_struct {
int a;
double b;
int c;
};
my_struct x = { 1, 2, 3 };
then ( void * )&x == ( void * )&x.a evaluates to 1.
Note: the casting is required because the operands have different types and there is no implicit conversion from one type to another.
One more example
#include <iostream>
#include <iomanip>
int main()
{
int y[] = { 1, 2, 3 };
std::cout << std::boolalpha
<< ( ( ( void * )&y == ( void * )y ) && ( ( void * )&y == ( void * )&y[0] ) && ( y == &y[0] ) )
<<'\n';
}
The program output is
true
All three expressions &y, y, and &y[0] have the same value (address). (An array used in an expression with rare exceptions is converted to pointer to its first element.)
The address of two separate declared variables are almost never equal (==).
Here, my_struct x = { 1, 2, 3 }; is declared separately from int y[] = { 1, 2, 3 };. When they're declared, they're given their own space in memory to occupy, so they're in two different spaces in memory. Even though the values stored by struct my_struct x and array int y[] are the same, they're stored in their own memory spaces.
If you want to see the actual memory locations, you can do this with a simple cout print statement:
cout << "&y[0]: " << &y[0] << endl;
cout << "&x.a: " << &x.a << endl;
&y[0] and &x.a are different addresses. If you are trying to check if they are the same, you can write a simple programm. And you will see the result.
struct my_struct {
int a;
double b;
int c;
};
int main()
{
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
std::cout << "&y[0] = " << &y[0] << "\n&x.a = " << &x.a << "\n&y[0]==&x.a = " << (&y[0]==&x.a);
}
The output is:
&y[0] = 0x72261501a440
&x.a = 0x72261501a450
&y[0]==&x.a = 0
So we can see different values of &y[0] and &x.a. They are not the same. and also &y[0]==&x.a = 0 and it means false
The & will return memory address (depending on your target platform that is usually 16 to 64 bit number, either representing physical memory address, or virtual logical address mapped to physical memory by OS (on modern OS like linux or MacOS, the user process doesn't see true physical addresses by default)).
So this part of source:
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
will instantiate both the structure and array in the memory as global variables, i.e. they will have memory addresses like 0x12345678, etc... and they will not overlap, if size of my_struct is for example 20 bytes, and x address is 0x1000, the array y will be in memory somewhere beyond it (address of y is also address of first element, in C/C++ the arrays are zero-cost abstraction, i.e. where the array starts, there's the first element already stored, and the rest of elements follow on consecutive memory addresses).
So your original expression &y[0] == &x.a is comparing one (absolute) address of particular element of the array with (absolute) address of structure member, and because they are instantiated in different regions of memory, the addresses will surely differ (as long as the index into array is within bounds) = false. You don't even need to check details which addresses precisely are compared.
But for completeness, the y[0] is the first element of array y, and address of that is identical to y itself. If there would be &y[1], that's address of second array element, with type int that means the &y[1] is equal to y+1 and/or to ((void*)y) + sizeof(int) ... in CPU machine code terms, that means if array starts at memory at address 0x2000, and int is 64 bits on your target platform, the second element starts at address 0x2008 (+8 bytes (64 bits) away from the start of array).
The &x.a is similarly full address where the actual value of member a resides in memory, so if the structure instance x starts at address 0x1000, the address of x.a will be also 0x1000 in this case (again zero cost of abstraction and it's simple struct type, if it would be class-like, having virtual functions, the member a would be probably a bit offset after the implicit virtual table pointer which is usually put at beginning of class/struct instance ... but this is implementation/platform specific, i.e. depends how particular compiler implements virtual functions/calls). For example the address of &x.b would be then 0x1008 (again I assume 64 bit int type, and I assume there's no extra padding applied in the my_struct, with different assumptions/conditions the offset of b from start of structure may be different than +8).
& gives you the address of an object.
&y gives you the address of the array y.
&y[0] gives you the address of the first element in array y which is equal to &y.
&x gives you the address of the struct x
&x.a gives you the address of the first member of the struct x which is equal to &x.
Since x and y are at different locations the addresses differ.
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.
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.
In GDB, info registers or info all-registers will show you all of the register symbol names and their values.
Question:
How do I get the variable name (i.e. from the source code) that is stored in that register? (or a line number in source code, or anything)
For example:
int my_reg = /* something */;
float another_reg = /* something else */;
...
Then perhaps, info all-registers will return:
R0 0x0 0
R1 0xfffbf0 16776176
R2 0x0 0
R3 0x0 0
R4 0x6 6
How do I determine which register (R0? R2? R4?) is "associated" with my_reg?
If you have access to the debug symbols (and understand how to read them - that is, you have some code that parses the debug symbols), it is possible to trace exactly which register corresponds to which register. However, this is quite possibly changing from one line to the next, as the compiler decides to move things around for one reason or another (e.g. some calculation starts with R1, and ends up with the result in R2, because that's better than trying to retain the value in R1 [or we need the original value in R1 too - think array[x++] - now we have the new value of x, hopefully in a register, and the value of the old x that we need to use for indexing, also needed to be in a register to add to the base-address of array.
Not all variables end up in registers (depending on processor, and "what registers are available").
The debugger WILL know where each variable is at any given time - but sometimes it can be a big confused, e.g:
int array[10000];
...
for(int i = 0; i < 10000; i++)
{
array[i] = rand();
}
may translate to something like this during optimization:
int array[10000];
int *ptr = array;
int *ptr2 = &array[10000];
while(ptr < ptr2)
{
*ptr++ = rand();
}
Now try printing i... ;)
There might be one register, multiple registers, or even no registers associated with any given C variable at any given point in time. You'll have to inspect the disassembly to see what's going on.
Why not just print my_reg to see the value?
l *$pc will list the source code around the current instruction being executed.
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