[Tutor] Help with using the ctypes module

Sachin Kamboj backslash42 at gmail.com
Mon Dec 13 17:27:49 CET 2010


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;
}




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20101213/cbf242dd/attachment.html>


More information about the Tutor mailing list