You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python的ctypes修改对象地址指向的参数值?

问题:通过ctypes修改Python对象的属性值

我正在为学校作业编写链表程序,遇到了技术问题:使用ctypes库时,已知某个对象的地址,如何修改该对象中存储地址的参数值?例如,要在链表末尾添加节点,已知尾节点(对象)的地址,需将其next属性从None改为新节点的地址。

我尝试了以下代码但未生效,以为是仅修改了对象引用而非地址中的实际值:

this_Node = ctypes.cast(this_pointer, ctypes.py_object).value
this_Node.next = new_node_adress

以下是完整代码:

import ctypes 

class Node:
    def __init__(self,data,next):
        self.data = data
        self.next = next 
#initialise linked list
LinkedList = []
for i in range(0,10):
    LinkedList.append(Node(i,None))
for i in range(0,9):
    LinkedList[i].next = id(LinkedList[i+1])
root_pointer= id(LinkedList[0])
#print(ctypes.cast(root_pointer, ctypes.py_object).value.data)

#search in linked list 
def search_value(root_pointer,f):
    found = False
    this_address = root_pointer
    this_Node = ctypes.cast(root_pointer, ctypes.py_object).value
    this_pointer = this_Node.next
    while this_Node.next != None and found == False:
        #print(this_Node.data)
        if f == this_Node.data:
            found = True
            print(f,"was found in address",this_address)
        else:
            this_address = this_Node.next
            this_Node = ctypes.cast(this_pointer, ctypes.py_object).value
            this_pointer = this_Node.next
    if found ==False:
        print(f,"was not in the list")
    return found, this_address,this_Node,this_pointer

def end_add(root_pointer,new_node_adress):
    this_address = root_pointer
    this_Node = ctypes.cast(root_pointer, ctypes.py_object).value
    this_pointer = this_Node.next
    while this_Node.next != None:
        this_address = this_Node.next
        this_Node = ctypes.cast(this_pointer, ctypes.py_object).value
        this_pointer = this_Node.next
    this_Node.next = new_node_adress
    

f = 34
a = Node(34,None)
end_add(root_pointer,id(a))
#print(ctypes.cast(root_pointer, ctypes.py_object).value.data)
found,this_address,this_Node,this_pointer=search_value(root_pointer,f)

解决方案

首先明确:你对ctypes.cast的使用是正确的,ctypes.cast(this_pointer, ctypes.py_object).value确实能获取对应地址的原Python对象,修改它的属性就是直接修改原对象的属性,不存在“只修改引用”的问题。代码未生效的根本原因是**search_value的遍历逻辑遗漏了最后一个节点**。

问题分析

你的Node类的next属性存储的是对象的id(整数类型地址),end_add函数已经正确将尾节点的next设置为新节点的id,但search_value的循环条件this_Node.next != None会在遍历到尾节点时直接退出,导致没有检查尾节点的data值,所以找不到新添加的节点。

修正步骤

  1. 调整search_value的遍历逻辑,先检查当前节点的data,再判断是否需要继续遍历下一个节点,确保覆盖所有节点。
  2. 简化end_add的遍历代码,去掉冗余的变量。

修正后的完整代码

import ctypes 

class Node:
    def __init__(self,data,next):
        self.data = data
        self.next = next 

# 初始化链表
LinkedList = []
for i in range(0,10):
    LinkedList.append(Node(i,None))
for i in range(0,9):
    LinkedList[i].next = id(LinkedList[i+1])
root_pointer= id(LinkedList[0])

# 链表查找函数
def search_value(root_pointer,f):
    found = False
    this_address = root_pointer
    this_Node = ctypes.cast(root_pointer, ctypes.py_object).value
    
    while True:
        # 先检查当前节点的数据
        if f == this_Node.data:
            found = True
            print(f,"was found in address",this_address)
            break
        # 没有下一个节点则退出循环
        if this_Node.next is None:
            break
        # 移动到下一个节点
        this_address = this_Node.next
        this_Node = ctypes.cast(this_address, ctypes.py_object).value
    
    if not found:
        print(f,"was not in the list")
    return found, this_address,this_Node

# 链表末尾添加节点函数
def end_add(root_pointer,new_node_adress):
    this_Node = ctypes.cast(root_pointer, ctypes.py_object).value
    # 遍历找到尾节点
    while this_Node.next != None:
        this_Node = ctypes.cast(this_Node.next, ctypes.py_object).value
    # 修改尾节点的next属性
    this_Node.next = new_node_adress

# 测试代码
f = 34
a = Node(34,None)
end_add(root_pointer,id(a))
found,this_address,this_Node = search_value(root_pointer,f)

关键说明

  • 修改对象属性的操作是有效的:this_Node = ctypes.cast(...)拿到的是原对象的引用,修改this_Node.next会直接改变原节点的属性值。
  • 遍历逻辑的调整是核心:确保每个节点的data都被检查到,包括最后一个节点。

内容的提问来源于stack exchange,提问作者Alejandro Sanchez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:25:07