C/Pointers
From Attie's Wiki
(Difference between revisions)
m |
m |
||
Line 67: | Line 67: | ||
==Memory Map== | ==Memory Map== | ||
− | These values and addresses will probably be different each time you run the program | + | 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 | ||
{|border="1" cellpadding="0" | {|border="1" cellpadding="0" | ||
− | ! Address !! Value !! ASCII !! Variable !! colspan="2" | Notes | + | ! Address !! Value !! ASCII !! Variable !! Valid? !! colspan="2" | Notes |
|- | |- | ||
− | + | | colspan="7" | ... | |
|- | |- | ||
− | | 0xBF893E93 || style="color:red" | 0x08 || ||? (MSB) || colspan="2" | | + | | 0xBF893E93 || style="color:red" | 0x08 || ||? (MSB) || No || colspan="2" | |
|- | |- | ||
− | | 0xBF893E92 || style="color:red" | 0x04 || ||? || colspan="2" | | + | | 0xBF893E92 || style="color:red" | 0x04 || ||? || No || colspan="2" | |
|- | |- | ||
− | | 0xBF893E91 || style="color:red" | 0x86 || ||? || colspan="2" | | + | | 0xBF893E91 || style="color:red" | 0x86 || ||? || No || colspan="2" | |
|- | |- | ||
− | | 0xBF893E90 || style="color:red" | 0x80 || ||? (LSB) || This is p[1] || 0xBF893E8C + (sizeof(char*) * 1) → 0xBF893E8C + (4 * 1) → 0xBF893E8C + 4 → 0xBF893E90 | + | | 0xBF893E90 || style="color:red" | 0x80 || ||? (LSB) || No || This is p[1] || 0xBF893E8C + (sizeof(char*) * 1) → 0xBF893E8C + (4 * 1) → 0xBF893E8C + 4 → 0xBF893E90 |
|- | |- | ||
− | | 0xBF893E8F || style="color:#4B2" | 0x08 || || s (MSB) || colspan="2" | | + | | 0xBF893E8F || style="color:#4B2" | 0x08 || || s (MSB) || Yes || colspan="2" | |
|- | |- | ||
− | | 0xBF893E8E || style="color:#4B2" | 0x04 || || s || colspan="2" | | + | | 0xBF893E8E || style="color:#4B2" | 0x04 || || s || Yes || colspan="2" | |
|- | |- | ||
− | | 0xBF893E8D || style="color:#4B2" | 0x87 || || s || colspan="2" | | + | | 0xBF893E8D || style="color:#4B2" | 0x87 || || s || Yes || colspan="2" | |
|- | |- | ||
− | | style="color:blue" | 0xBF893E8C || style="color:#4B2" | 0x34 || || s (LSB) || This is p[0] || 0xBF893E8C + (sizeof(char*) * 0) → 0xBF893E8C + (4 * 0) → 0xBF893E8C + 0 → 0xBF893E8C | + | | style="color:blue" | 0xBF893E8C || style="color:#4B2" | 0x34 || || s (LSB) || Yes || This is p[0] || 0xBF893E8C + (sizeof(char*) * 0) → 0xBF893E8C + (4 * 0) → 0xBF893E8C + 0 → 0xBF893E8C |
|- | |- | ||
− | | 0xBF893E8B || style="color:blue" | 0xBF || || p (MSB) || colspan="2" | | + | | 0xBF893E8B || style="color:blue" | 0xBF || || p (MSB) || Yes || colspan="2" | |
|- | |- | ||
− | | 0xBF893E8A || style="color:blue" | 0x89 || || p || colspan="2" | | + | | 0xBF893E8A || style="color:blue" | 0x89 || || p || Yes || colspan="2" | |
|- | |- | ||
− | | 0xBF893E89 || style="color:blue" | 0x3E || || p || colspan="2" | | + | | 0xBF893E89 || style="color:blue" | 0x3E || || p || Yes || colspan="2" | |
|- | |- | ||
− | | 0xBF893E88 || style="color:blue" | 0x8C || || p (LSB) || colspan="2" | | + | | 0xBF893E88 || style="color:blue" | 0x8C || || p (LSB) || Yes || colspan="2" | |
|- | |- | ||
− | + | | colspan="7" | ... | |
|- | |- | ||
− | | 0x08048737 || 0x00 || '\0' || || This is s[3] || 0x08048734 + (sizeof(char) * 3) → 0x08048734 + (1 * 3) → 0x08048734 + 3 → 0x08048737 | + | | 0x08048737 || 0x00 || '\0' || || Yes || This is s[3] || 0x08048734 + (sizeof(char) * 3) → 0x08048734 + (1 * 3) → 0x08048734 + 3 → 0x08048737 |
|- | |- | ||
− | | 0x08048736 || 0x63 || 'a' || || This is s[2] || 0x08048734 + (sizeof(char) * 2) → 0x08048734 + (1 * 2) → 0x08048734 + 2 → 0x08048736 | + | | 0x08048736 || 0x63 || 'a' || || Yes || This is s[2] || 0x08048734 + (sizeof(char) * 2) → 0x08048734 + (1 * 2) → 0x08048734 + 2 → 0x08048736 |
|- | |- | ||
− | | 0x08048735 || 0x62 || 'b' || || This is s[1] || 0x08048734 + (sizeof(char) * 1) → 0x08048734 + (1 * 1) → 0x08048734 + 1 → 0x08048735 | + | | 0x08048735 || 0x62 || 'b' || || Yes || This is s[1] || 0x08048734 + (sizeof(char) * 1) → 0x08048734 + (1 * 1) → 0x08048734 + 1 → 0x08048735 |
|- | |- | ||
− | | style="color:#4B2" | 0x08048734 || 0x63 || 'c' || || This is s[0] || 0x08048734 + (sizeof(char) * 0) → 0x08048734 + (1 * 0) → 0x08048734 + 0 → 0x08048734 | + | | style="color:#4B2" | 0x08048734 || 0x63 || 'c' || || Yes || This is s[0] || 0x08048734 + (sizeof(char) * 0) → 0x08048734 + (1 * 0) → 0x08048734 + 0 → 0x08048734 |
|- | |- | ||
− | + | | colspan="7" | ... | |
|- | |- | ||
− | | style="color:red" | 0x08048680 || 0x55 || || || colspan="2" | | + | | style="color:red" | 0x08048680 || 0x55 || || || No || colspan="2" | |
|- | |- | ||
− | + | | colspan="7" | ... | |
|} | |} |
Revision as of 00:06, 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
$ 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
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 | ||||
... |