J'essayais d'utiliser le module ctypes pour un projet. Je créais un tableau dynamiquement alloué de paires "max_entries" et une fois le tableau épuisé, je créais un nouveau tableau de taille (1.5 * max_entries) et copiais le contenu de l'ancien tableau dans le nouveau tableau.Module ctypes Python: Accès au pointeur NULL lors de l'extension du tableau de pointeurs
Malheureusement, lorsque j'essaie d'accéder au contenu de cette nouvelle arborescence, j'obtiens une exception "NULL pointer access". Le code C correspondant semble fonctionner parfaitement. (Voir le code ci-dessous.)
Je me demandais s'il me manquait quelque chose sur le fonctionnement du module ctypes. Toute aide serait grandement appréciée. (Je ne sais pas si c'est la liste de diffusion appropriée pour ma question.)
/mercis!
#!/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)
Maintenant, malheureusement, lorsque je tente d'exécuter ce code, je reçois une exception "accès pointeur NULL":
$ 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
Les travaux de code C correspondant parfaitement:
#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;
}