4

Pythonでダングリングポインタを作成する方法はありますか?たとえば、オブジェクトを手動で削除する必要があると思います。そうすると、そのオブジェクトの参照は、プログラムにとって意味のない場所を指します。私はこの例をここで見つけました

import weakref
class Object:
    pass

o = Object()    #new instance
print ("o id is:",id(o))
r = weakref.ref(o)
print ("r id is:",id(r))
o2 = r()
print ("o2 id is:",id(o2))
print ("r() id is:",id(r()))
print (o is o2)         

del o,o2
print (r(),r)   #If the referent no longer exists, calling the reference object returns None

o = r()         # r is a weak reference object
if o is None:
    # referent has been garbage collected
    print ("Object has been deallocated; can't frobnicate.")
else:
    print ("Object is still live!")
    o.do_something_useful()

この例では、ダングリングポインタ/参照はどれですか?それはoまたはrですか?私は混乱しています。スタックにダングリングポインタを作成することも可能ですか?よろしければ、簡単な例をいくつか挙げてください。そうすれば、どうなるか理解できます。前もって感謝します。

4

3 に答える 3

4

すべてのPythonオブジェクトはヒープ上に存在します。スタックは関数呼び出しにのみ使用されます。

weakrefオブジェクトを呼び出すと、オブジェクトが逆参照され、オブジェクトがまだ存在する場合は、オブジェクトへの強力な参照が得られます。それ以外の場合は、を取得しますNone。後者の場合、weakrefを「ダングリング」と呼ぶことができます(rあなたの例では)。

ただし、Pythonには、Cと同じように「ダングリングポインタ」の概念はありません。ctypes定義上、強い参照は参照先を存続させるため、削除されたオブジェクトを参照する名前(強い参照)を作成することはできません(Pythonのバグ、バグのある拡張モジュール、またはのようなモジュールの誤用を除く)。一方、弱参照はNone、指示対象が削除された場合に自動的に解決されるため、実際にはダングリングポインターではありません。

ctypes悪用すると、「実際の」ダングリングポインタを作成できることに注意してください。

import ctypes
a = (1, 2, 3)
ctypes.pythonapi.Py_DecRef(ctypes.py_object(a))
print a

あなたprint aが今定義されていないときに何が起こるか。インタプリタがクラッシュしたり、印刷(1, 2, 3)したり、他のタプルを印刷したり、ランダムな関数を実行したりする可能性があります。もちろん、これはあなたが虐待したためにのみ可能ですctypes; それはあなたがするべきことはありません。

于 2012-09-29T20:41:06.963 に答える
2

Pythonまたは拡張機能のバグがなければ、割り当て解除されたオブジェクトを参照する方法はありません。弱参照は、オブジェクトが生きている限りオブジェクトを参照しますが、オブジェクトの存続には寄与しません。オブジェクトの割り当てが解除されると、弱参照はNoneと評価されるため、ぶら下がっているオブジェクトを取得することはありません。(オブジェクトがすでに割り当て解除され、weakrefがNoneに逆参照された後で、弱参照のコールバックが呼び出されるため、それを復活させることもできません。)

実際に割り当て解除されたオブジェクトを参照できる場合、Pythonは最初のアクセスでクラッシュする可能性があります。これは、オブジェクトが以前に保持していたメモリが再利用され、オブジェクトのタイプやその他のスロットにガベージが含まれるためです。Pythonオブジェクトがスタックに割り当てられることはありません。

ぶら下がっているオブジェクトを使用する必要があるユースケースがある場合は、質問の形式でユースケースを提示する必要があります。

于 2012-09-29T14:16:48.417 に答える
1

弱参照を作成すると、参照されたオブジェクトが削除されたとき(参照カウントがゼロに達したとき、または他のオブジェクトによって参照されていないオブジェクトのクローズドサイクルの一部であるとき)に「ぶら下がり」になります。これが可能なweakrefのは、参照カウント自体が増加しないためです(これが弱参照の要点です)。

これが発生すると、weakrefオブジェクトを「逆参照」(呼び出す)するたびに、が返されますNone

Pythonでは、変数は実際には名前であり、オブジェクトを指していることを覚えておくことが重要です。それらは実際には「強力な参照」です。例:

import weakref

class A:
    pass

# a new object is created, and the name "x" is set to reference the object,
# giving a reference count of 1
x = A() 

# a weak reference is created referencing the object that the name x references
# the reference count is still 1 though, because x is still the only strong
# reference
weak_reference = weakref.ref(x)

# the only strong reference to the object is deleted (x), reducing the reference
# count to 0 this means that the object is destroyed, and at this point
# "weak_reference" becomes dangling, and calls return None
del x

assert weak_reference() is None
于 2012-09-29T14:07:10.800 に答える