I confess I don't know a lot about C so I may be off base here... But it looks like your c func extendarray returns a pointer to the new extended array, but you are not capturing this pointer in your python when you call the c func. So the python code is pointing at the old deallocated array.
Does that make sense and/or point you in the right direction? ----------------------------- Sent from a mobile device with a bad e-mail client. ----------------------------- On Dec 13, 2010, at 10:27 AM, Sachin Kamboj <backslas...@gmail.com> wrote: > Hi All, > > 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. > > 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.) > > 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.) > > /Thanks! > > --- > > #!/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) > > --- > Now unfortunately, when I try to run this code, I am getting a "NULL pointer > access" exception: > > $ 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 <module> > 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 > > --- > > The corresponding C code works perfectly: > > #include <stdio.h> > #include <stdlib.h> > #include <math.h> > > 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->entries; > long long new_max_entries = ceil(1.5 * x->max_entries); > > printf("Extending Array\n"); > printf("Before: %lld/%lld\n", x->no_entries, x->max_entries); > > x->entries = malloc(sizeof(pair *) * new_max_entries); > for (i = 0; i < 100; ++i) { > x->entries[i] = old_entries[i]; > } > x->max_entries = new_max_entries; > free(old_entries); > > printf("After: %lld/%lld\n", x->no_entries, x->max_entries); > return x; > } > > void print_pair(pair *p) { > printf("%ld\t%ld\n", p->a, p->b); > } > > void print_array(my_arr *x) { > int i; > printf("Printing %lld/%lld entries\n", x->no_entries, x->max_entries); > for (i = 0; i < x->no_entries; ++i) { > print_pair(x->entries[i]); > } > } > > int main(int argc, char *argv[]) > { > int i; > my_arr x = { > 0, > 10, > malloc(sizeof(pair *) * 10) > }; > > for (i = 0; i < 100; ++i) { > if (x.no_entries == x.max_entries) { > extend_array(&x); > } > pair *my_pair = malloc(sizeof(pair)); > my_pair->a = i; > my_pair->b = rand() % 100; > > x.entries[x.no_entries++] = my_pair; > print_pair(x.entries[i]); > } > print_array(&x); > return 0; > } > > > _______________________________________________ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor
_______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor