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