-2

I'm starting a unit on Software Security - in some prelim reading, I've come across the following pointer syntax and I'm not sure I understand.

int  x = 20;
int* p = &x;
int  k = *(p+1);

What is k in the example?

I know if I have an array like so:

int  j[10] = {0};
int  k  = *(j+1);

such syntax will de-reference the int (system's sizeof(int)) at location 1 of array j.

So how does this work with the non-array example above?

wulfgarpro
  • 6,666
  • 12
  • 69
  • 110

4 Answers4

2

Pointer arithmetics *(p+1) syntax that adds an int to a pointer is equivalent to p[i]. It assumes that p points into a block of a sufficient size, otherwise the dereference causes undefined behavior.

Note that you do not need to initialize a pointer using an array new. You can use an array in the automatic memory, point to an existing array, or even point into the middle of another array, like this:

int data[20] = {0, 1, 2, 3, 4, 5, 6, ...};
int *p = &data[5]; // Point to element at index five
int x = *(p+1);    // Access element at index six
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

Pointer to value is indistinguishable from pointer to first element of an array.

So int*p = &x is pointer to first element of an array where only one element is allocated. Now *(p+1) is accessing second element on that array - which is access element out of bounds of the array and is undefined behavior (Array index out of bound in C). Valid results for such operation range from world destruction to no-op.

One likely case is *(p+1) would refer to whole/part of p itself as usually variables are allocated sequentially. So there is a good chance nothing spectacular to happen and bug will stay unnoticed for some time. Code reviews and generally being concerned about such code is good practice to prevent those.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
1

In the first example you are pointing to the item in memory directly after x. The memory after x will be the address of x, contained in p.

Keep in mind that this is a generalization, this could change depending on a few things, so it is undefined behaviour. Try adding the line:

printf("&x: %p\n p: %p\n&k: %p\n k: %08x\n", &x, p, &k, k);

and running the code in main. This should print out the memory addresses and the hex value of k. It should give you a more clear idea of what exactly is happening in memory.

Note that if you change the order of your variables the output will change. You should get used to how memory works and why this kind of thing is undefined behaviour (and therefore should never be used for anything besides learning purposes).

Jacob H
  • 864
  • 1
  • 10
  • 25
1

Here's a code sample I wrote to play with this syntax by breaking an int up into it's constituent bytes.

#include <stdio.h>

int main(void) {
    int  i = 9;
    int* p = &i;

    char* c = (char*)&i; 
    printf("%08X\n", *c);
    printf("%08X\n", *(c+1));
    printf("%08X\n", *(c+2));
    printf("%08X\n", *(c+3));

    return 0;
}

➜  tmp git:(master) ✗ ./q3          
00000009
00000000
00000000
00000000
wulfgarpro
  • 6,666
  • 12
  • 69
  • 110