title: Python ctypes module: NULL pointer access while extending pointer array
body: <p>I was trying to use the ctypes module for a project. I was creating a dynamically allocated array of "max_entries" pairs and once the array was exhausted, I was creating a new array of size (1.5 * max_entries) and copying the contents from the old array to the new array. </p>
  
  <p>Unfortunately, when I try to access the contents of this new_array, I get a "NULL pointer access" exception. The corresponding C code seems to work perfectly. (See code below.)</p>
  
  <p>I was wondering if I was missing something about the way the ctypes module works. Any help would be greatly appreciated. (Not sure if this is the appropriate mailing list for my question.)</p>
  
  <p>/Thanks!</p>
  
  <hr>
  
  <pre><code>#!/usr/bin/env python
  
  from ctypes import *
  import math
  import random
  
  
  class PAIR(Structure):
      _fields_ = [("a", c_long),
                  ("b", c_long)]
  
  
  class MY_ARR(Structure):
      _fields_ = [("no_entries", c_longlong),
                  ("max_entries", c_longlong),
                  ("entries", POINTER(POINTER(PAIR)))
                  ]
  
  def extendArray(x):
      print "Extending Array"
      print "Before: %d/%d" % (x.no_entries, x.max_entries)
      old_arr = x.entries
  
      # Create a new array
      new_max_entries = int(math.ceil(1.5 * x.max_entries))
      x.entries = (POINTER(PAIR) * new_max_entries)()
  
      # Copy the entries from the old array to the new array
      for i in range(x.no_entries):
          x.entries[i] = old_arr[i]
  
      x.max_entries = new_max_entries
      print "After: %d/%d" % (x.no_entries, x.max_entries)
      return x
  
  def printPair(x):
      print x.contents.a, x.contents.b
  
  def printArray(x):
      print "Printing %d/%d Entries" % (x.no_entries, x.max_entries)
      for i in range(x.no_entries):
          printPair(x.entries[i])
  
  
  if __name__ == "__main__":
      x = MY_ARR(0, 10, (POINTER(PAIR) * 10)())
      for i in range(100):
          if x.no_entries == x.max_entries:
              print "\n\nPrinting Before Extension"
              printArray(x)
  
              extendArray(x)
  
              print "\n\nPrinting After Extension"
              printArray(x)
  
          my_pair = PAIR(i, random.randint(0, 100))
          x.entries[x.no_entries] = pointer(my_pair)
          x.no_entries += 1
  
          printPair(x.entries[i])
  
      printArray(x)
  </code></pre>
  
  <hr>
  
  <p>Now unfortunately, when I try to run this code, I am getting a "NULL pointer access" exception:</p>
  
  <pre><code>$ python TestExtension.py 
  0 40
  1 40
  2 11
  3 36
  4 82
  5 73
  6 93
  7 100
  8 75
  9 80
  
  
  Printing Before Extension
  Printing 10/10 Entries
  0 40
  1 40
  2 11
  3 36
  4 82
  5 73
  6 93
  7 100
  8 75
  9 80
  Extending Array
  Before: 10/10
  After: 10/15
  
  
  Printing After Extension
  Printing 10/15 Entries
  Traceback (most recent call last):
    File "TestExtension.py", line 55, in &lt;module&gt;
      printArray(x)
    File "TestExtension.py", line 42, in printArray
      printPair(x.entries[i])
    File "TestExtension.py", line 37, in printPair
      print x.contents.a, x.contents.b
  ValueError: NULL pointer access
  </code></pre>
  
  <hr>
  
  <p>The corresponding C code works perfectly:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;math.h&gt;
  
  typedef struct {
      long a;
      long b;
  } pair;
  
  typedef struct {
      long long no_entries;
      long long max_entries;
      pair **entries;
  } my_arr;
  
  my_arr *extend_array(my_arr *x) {
      int i;
      pair **old_entries = x-&gt;entries;
      long long new_max_entries = ceil(1.5 * x-&gt;max_entries);
  
      printf("Extending Array\n");
      printf("Before: %lld/%lld\n", x-&gt;no_entries, x-&gt;max_entries);
  
      x-&gt;entries = malloc(sizeof(pair *) * new_max_entries);
      for (i = 0; i &lt; 100; ++i) {
          x-&gt;entries[i] = old_entries[i];
      }
      x-&gt;max_entries = new_max_entries;
      free(old_entries);
  
      printf("After: %lld/%lld\n", x-&gt;no_entries, x-&gt;max_entries);
      return x;
  }
  
  void print_pair(pair *p) {
      printf("%ld\t%ld\n", p-&gt;a, p-&gt;b);
  }
  
  void print_array(my_arr *x) {
      int i;
      printf("Printing %lld/%lld entries\n", x-&gt;no_entries, x-&gt;max_entries);
      for (i = 0; i &lt; x-&gt;no_entries; ++i) {
          print_pair(x-&gt;entries[i]);
      }
  }
  
  int main(int argc, char *argv[])
  {
      int i;
      my_arr x = {
          0, 
          10,
          malloc(sizeof(pair *) * 10)
      };
  
      for (i = 0; i &lt; 100; ++i) {
          if (x.no_entries == x.max_entries) {
              extend_array(&amp;x);
          }
          pair *my_pair = malloc(sizeof(pair));
          my_pair-&gt;a = i;
          my_pair-&gt;b = rand() % 100;
  
          x.entries[x.no_entries++] = my_pair;
          print_pair(x.entries[i]);
      }
      print_array(&amp;x);
      return 0;
  }
  </code></pre>