gpt4 book ai didi

Python ctypes 模块 : NULL pointer access while extending pointer array

转载 作者:太空宇宙 更新时间:2023-11-03 11:10:41 25 4
gpt4 key购买 nike

我试图将 ctypes 模块用于一个项目。我创建了一个动态分配的“max_entries”对数组,一旦数组用完,我就创建了一个大小为 (1.5 * max_entries) 的新数组,并将内容从旧数组复制到新数组。

不幸的是,当我试图访问这个 new_array 的内容时,我得到了一个“NULL pointer access”异常。相应的 C 代码似乎可以完美运行。 (见下面的代码。)

我想知道我是否遗漏了一些关于 ctypes 模块工作方式的信息。任何帮助将不胜感激。 (不确定这是否适合我的问题。)

/谢谢!


#!/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)

不幸的是,当我尝试运行这段代码时,出现了“NULL pointer access”异常:

$ 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

相应的 C 代码完美运行:

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

最佳答案

问题是语句

old_arr = x.entries

没有按照您的预期去做。查看 old_arr._b_base_,您会发现它是一个指向 MY_ARR 的指针。所以当底层指针发生变化时,old_arr 突然指向新数组,循环分配了很多空指针。要解决此问题,请编写

new_max_entries = int(math.ceil(1.5 * x.max_entries))
new_entries = (POINTER(PAIR) * new_max_entries)()

# Copy the entries from the old array to the new array
for i in range(x.no_entries):
new_entries[i] = x.entries[i]

x.entries = new_entries
x.max_entries = new_max_entries

关于Python ctypes 模块 : NULL pointer access while extending pointer array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4431329/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com