title: Double and triple pointers in C
body: <p>I have a small program as shown below.This program is an attempt to better understand pointers in 'C' how variables are arranged in memory.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  const char *c = "hello";
  const char **cp = &amp;c;
  const char ***cpp = &amp;cp;
  const char ****cppp = &amp;cpp;
  
  int main()
  {
  
      printf("PTR (c)       : %p \n",c);
      printf("PTR (cp)      : %p \n",cp);
      printf("PTR (cpp)     : %p \n",cpp);
      printf("PTR (cppp)    : %p \n",cppp);
      printf("CONTENT (c)   : %c \n",*c);
      printf("CONTENT (cp)  : 0x%x \n",*(unsigned int*)cp);
      printf("CONTENT (cpp) : 0x%x \n",*(unsigned int*)cpp);
      printf("CONTENT (cppp): 0x%x \n",*(unsigned int*)cppp);
      return 0;
  }
  </code></pre>
  
  <p>The output that I get on my PC (Ubuntu 12.04) x86_64 is as follows</p>
  
  <pre><code>PTR (c)       : 0x4006dc 
  PTR (cp)      : 0x601020 
  PTR (cpp)     : 0x601028 
  PTR (cppp)    : 0x601030 
  CONTENT (c)   : h 
  CONTENT (cp)  : 0x4006dc 
  CONTENT (cpp) : 0x601020 
  CONTENT (cppp): 0x601028 
  </code></pre>
  
  <p>The output looks good since </p>
  
  <ul>
  <li>cp contains the address of c</li>
  <li>cpp contains the address of cp </li>
  <li>cppp contains the address of cpp</li>
  </ul>
  
  <p>Now I do an nm on the binary executable of the above program.</p>
  
  <pre><code>0000000000600e50 d _DYNAMIC
  0000000000600fe8 d _GLOBAL_OFFSET_TABLE_
  00000000004006d8 R _IO_stdin_used
                   w _Jv_RegisterClasses
  0000000000600e30 d __CTOR_END__
  0000000000600e28 d __CTOR_LIST__
  0000000000600e40 D __DTOR_END__
  0000000000600e38 d __DTOR_LIST__
  0000000000400860 r __FRAME_END__
  0000000000600e48 d __JCR_END__
  0000000000600e48 d __JCR_LIST__
  0000000000601040 A __bss_start
  0000000000601010 D __data_start
  0000000000400690 t __do_global_ctors_aux
  0000000000400460 t __do_global_dtors_aux
  0000000000601018 D __dso_handle
                   w __gmon_start__
  0000000000600e24 d __init_array_end
  0000000000600e24 d __init_array_start
  0000000000400680 T __libc_csu_fini
  00000000004005f0 T __libc_csu_init
                   U __libc_start_main@@GLIBC_2.2.5
  0000000000601040 A _edata
  0000000000601050 A _end
  00000000004006c8 T _fini
  00000000004003c8 T _init
  0000000000400410 T _start
  0000000000601020 D c
  000000000040043c t call_gmon_start
  0000000000601040 b completed.6531
  0000000000601028 D cp
  0000000000601030 D cpp
  0000000000601038 D cppp
  0000000000601010 W data_start
  0000000000601048 b dtor_idx.6533
  00000000004004d0 t frame_dummy
  00000000004004f4 T main
                   U printf@@GLIBC_2.2.5
  </code></pre>
  
  <p>Below I have repasted the relevant lines of intrest.</p>
  
  <pre><code>0000000000601020 D c
  0000000000601028 D cp
  0000000000601030 D cpp
  0000000000601038 D cppp
  </code></pre>
  
  <p>To the best of my understanding the interpretation is as follows.</p>
  
  <p>'c' is a part of the data segment (denoted by 'D') and is at address 0000000000601020
  According to my program that is the address of 'cp'.This is the case with all the variables.</p>
  
  <p>Am I missing something vital here.It is a beginners attempt to understand C pointers well.</p>