C/Pointers
From Attie's Wiki
(Difference between revisions)
m |
m (→Memory Map) |
||
Line 68: | Line 68: | ||
==Memory Map== | ==Memory Map== | ||
+ | This map relates to the execution trace above<br> | ||
These values and addresses will probably be different each time you run the program<br> | These values and addresses will probably be different each time you run the program<br> | ||
Accessing memory that has been marked as not valid in this table is a '''bad''' idea. It will very commonly make your program SEGFAULT | Accessing memory that has been marked as not valid in this table is a '''bad''' idea. It will very commonly make your program SEGFAULT |
Revision as of 00:12, 9 March 2012
A helper for people starting out with pointers:
test.c
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #define P(expr) printf("%10s: 0x%02X\n", #expr, expr) int main(void) { char *s = "cba"; char **p = &s; P( s ); P( &s ); P( s[0] ); P( *s ); P( p ); P( &p ); P( p[0] ); P( *p ); P( p[1] ); P( *p[1] ); P( (*p)[1] ); P( *(p[1]) ); P( (*p) ); P( (*p)++ ); P( (*p)[0] ); P( (*p) ); P( ++(*p) ); P( (*p)[0] ); P( (*p) ); return 0; }
Output
Note the difference between *p[1]
, (*p)[1]
and *(p[1])
.
$ gcc test.c -o test && ./test s: 0x8048734 <-- the address of the 'c' &s: 0xBF893E8C <-- the address of the variable s s[0]: 0x63 <-- the 'c' *s: 0x63 <-- the 'c' p: 0xBF893E8C <-- the address of the variable s &p: 0xBF893E88 <-- the address of the variable p p[0]: 0x8048734 <-- the address of the 'c' *p: 0x8048734 <-- the address of the 'c' p[1]: 0x8048680 <-- INVALID - the value stored just after the variable p (the program may segfault here) *p[1]: 0x55 <-- INVALID - the value stored at location 0x8048680 (again, the program may segfault here) (*p)[1]: 0x62 <-- the 'b' *(p[1]): 0x55 <-- INVALID - the same as *p[1] (*p): 0x8048734 <-- the address of the 'c' (*p)++: 0x8048734 <-- the address of the 'c' - the pointer is POST incremented (*p)[0]: 0x62 <-- the 'b' (*p): 0x8048735 <-- the address of the 'b' ++(*p): 0x8048736 <-- the address of the 'a' - the pointer is PRE incremented (*p)[0]: 0x61 <-- the 'a' (*p): 0x8048736 <-- the address of the 'a'
Memory Map
This map relates to the execution trace above
These values and addresses will probably be different each time you run the program
Accessing memory that has been marked as not valid in this table is a bad idea. It will very commonly make your program SEGFAULT
Address | Value | ASCII | Variable | Valid? | Notes | |
---|---|---|---|---|---|---|
... | ||||||
0xBF893E93 | 0x08 | ? (MSB) | No | |||
0xBF893E92 | 0x04 | ? | No | |||
0xBF893E91 | 0x86 | ? | No | |||
0xBF893E90 | 0x80 | ? (LSB) | No | This is p[1] | 0xBF893E8C + (sizeof(char*) * 1) → 0xBF893E8C + (4 * 1) → 0xBF893E8C + 4 → 0xBF893E90 | |
0xBF893E8F | 0x08 | s (MSB) | Yes | |||
0xBF893E8E | 0x04 | s | Yes | |||
0xBF893E8D | 0x87 | s | Yes | |||
0xBF893E8C | 0x34 | s (LSB) | Yes | This is p[0] | 0xBF893E8C + (sizeof(char*) * 0) → 0xBF893E8C + (4 * 0) → 0xBF893E8C + 0 → 0xBF893E8C | |
0xBF893E8B | 0xBF | p (MSB) | Yes | |||
0xBF893E8A | 0x89 | p | Yes | |||
0xBF893E89 | 0x3E | p | Yes | |||
0xBF893E88 | 0x8C | p (LSB) | Yes | |||
... | ||||||
0x08048737 | 0x00 | '\0' | Yes | This is s[3] | 0x08048734 + (sizeof(char) * 3) → 0x08048734 + (1 * 3) → 0x08048734 + 3 → 0x08048737 | |
0x08048736 | 0x63 | 'a' | Yes | This is s[2] | 0x08048734 + (sizeof(char) * 2) → 0x08048734 + (1 * 2) → 0x08048734 + 2 → 0x08048736 | |
0x08048735 | 0x62 | 'b' | Yes | This is s[1] | 0x08048734 + (sizeof(char) * 1) → 0x08048734 + (1 * 1) → 0x08048734 + 1 → 0x08048735 | |
0x08048734 | 0x63 | 'c' | Yes | This is s[0] | 0x08048734 + (sizeof(char) * 0) → 0x08048734 + (1 * 0) → 0x08048734 + 0 → 0x08048734 | |
... | ||||||
0x08048680 | 0x55 | No | ||||
... |