Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何处理在方法中间内存中移动的对象? 我在C++中编写了一个VC++语言,用于编程语言。语言是垃圾收集的,所以我有在垃圾回收堆中分配的C++类的实例。我使用的是复制收集器,所以当GC发生时,这些对象会在内存中移动。这意味着需要更新指向该对象的每个指针。除了一个棘手的问题:this,大多数指针都很容易处理。考虑: class SomeObj : public Managed // inheriting from this means it's on the GC heap { public: void method() { SomeObj* other = new SomeObj(); // could trigger a GC. printf("%d\n", someField); // this points to wrong memory } private: int someField; }; 如果我处于某个对象的实例方法的中间,该对象存在于GC堆中,那么此< /COD>指向GC内存。在这个方法的中间可以出现一个集合。发生这种情况时,对象将移动到新位置。但是,由于我们处于方法调用的中间,这个仍然指向旧错误的位置。_C++_Garbage Collection_Programming Languages_Vm Implementation - Fatal编程技术网 指向GC内存。在这个方法的中间可以出现一个集合。发生这种情况时,对象将移动到新位置。但是,由于我们处于方法调用的中间,这个仍然指向旧错误的位置。,c++,garbage-collection,programming-languages,vm-implementation,C++,Garbage Collection,Programming Languages,Vm Implementation" /> 指向GC内存。在这个方法的中间可以出现一个集合。发生这种情况时,对象将移动到新位置。但是,由于我们处于方法调用的中间,这个仍然指向旧错误的位置。,c++,garbage-collection,programming-languages,vm-implementation,C++,Garbage Collection,Programming Languages,Vm Implementation" />

如何处理在方法中间内存中移动的对象? 我在C++中编写了一个VC++语言,用于编程语言。语言是垃圾收集的,所以我有在垃圾回收堆中分配的C++类的实例。我使用的是复制收集器,所以当GC发生时,这些对象会在内存中移动。这意味着需要更新指向该对象的每个指针。除了一个棘手的问题:this,大多数指针都很容易处理。考虑: class SomeObj : public Managed // inheriting from this means it's on the GC heap { public: void method() { SomeObj* other = new SomeObj(); // could trigger a GC. printf("%d\n", someField); // this points to wrong memory } private: int someField; }; 如果我处于某个对象的实例方法的中间,该对象存在于GC堆中,那么此< /COD>指向GC内存。在这个方法的中间可以出现一个集合。发生这种情况时,对象将移动到新位置。但是,由于我们处于方法调用的中间,这个仍然指向旧错误的位置。

如何处理在方法中间内存中移动的对象? 我在C++中编写了一个VC++语言,用于编程语言。语言是垃圾收集的,所以我有在垃圾回收堆中分配的C++类的实例。我使用的是复制收集器,所以当GC发生时,这些对象会在内存中移动。这意味着需要更新指向该对象的每个指针。除了一个棘手的问题:this,大多数指针都很容易处理。考虑: class SomeObj : public Managed // inheriting from this means it's on the GC heap { public: void method() { SomeObj* other = new SomeObj(); // could trigger a GC. printf("%d\n", someField); // this points to wrong memory } private: int someField; }; 如果我处于某个对象的实例方法的中间,该对象存在于GC堆中,那么此< /COD>指向GC内存。在这个方法的中间可以出现一个集合。发生这种情况时,对象将移动到新位置。但是,由于我们处于方法调用的中间,这个仍然指向旧错误的位置。,c++,garbage-collection,programming-languages,vm-implementation,C++,Garbage Collection,Programming Languages,Vm Implementation,我可以通过不在托管内存中的类上使用实例方法来解决这个问题,但我确实喜欢这样的代码更简单。有什么技巧可以解决这个问题吗?您可以引入另一个间接层次。我将以你为例: class SomeData : public Managed { int someField; }; class SomeObj : public Managed // inheriting from this means it's on the GC heap { public: void method() {

我可以通过不在托管内存中的类上使用实例方法来解决这个问题,但我确实喜欢这样的代码更简单。有什么技巧可以解决这个问题吗?

您可以引入另一个间接层次。我将以你为例:

class SomeData : public Managed
{
 int someField;
};

class SomeObj : public Managed      // inheriting from this means it's on the GC heap
{
public:
  void method()
  {
    SomeObj* other = new SomeObj(); // could trigger a GC.
    printf("%d\n", someData->someField);      // this points to wrong memory
  }

private:
  SomeObjData* someData;
};

请注意,托管的每个实现都需要这样做。

您的GC需要扫描堆栈和寄存器中的指针并修复它们。如果VM支持多线程,则需要在扫描所有线程堆栈时挂起它们。“this”指针将位于堆栈或寄存器中

<>因为C++不提供栈的类型信息,所以你可能会遇到类似

之类的困难
int i = 1000000;
char * p = new char[10]; // 0xF4240 = 1000000
无论您使用什么方法来移动其他指针,都会遇到同样的问题。在某些情况下,代码必须将句柄转换为指针,这些指针需要修复

像这样修改C++代码< /P>

func()->method()
struct GCroot obj123 = { /* .. */ };
obj123.ptr->x = obj123.ptr->x + 1;
load r1, obj123.ptr
load r2, (r1)
add r2, 1
store (r1), r2

struct GCroot call123 = { func() };
call123.obj->method();
多线程问题。如果你有这样的代码

func()->method()
struct GCroot obj123 = { /* .. */ };
obj123.ptr->x = obj123.ptr->x + 1;
load r1, obj123.ptr
load r2, (r1)
add r2, 1
store (r1), r2
它可能会生成如下的伪汇编代码

func()->method()
struct GCroot obj123 = { /* .. */ };
obj123.ptr->x = obj123.ptr->x + 1;
load r1, obj123.ptr
load r2, (r1)
add r2, 1
store (r1), r2

如果另一个线程在第一个asm行和最后一个asm行之间的任何时间执行GC,r1如何修复?

只是
方法
的一个隐藏参数。你可以随心所欲,比如说,你可以
删除这个this
,而是任何本地指针变量:
void SomeObj::method(){int*x=&m_int;dou some_引起的东西_GC();use(x)}
(编译器可能会将
x
放入寄存器中。)如果您有一个二叉树(每个节点有2个指针),什么代码修复了GC后的所有指针?我认为复制收集器需要引入另一个间接级别。如果您知道
在哪里,您的GC可以更新它,它要么在堆栈上,要么在寄存器中。问题是您不知道
在哪里?如果是这样,那么我认为您有更严重的问题。有没有你看过Boehm conservative垃圾收集器了吗?它有GC,但不移动对象,并且被广泛使用。这段代码不是也有同样的问题吗?GC移动当前对象,
不再有效,对
某些数据的访问崩溃。其他指针在这里没有任何问题。我可以将它们封装在一个让他们看得到的根,GC可以直接找到它们。在调用任何一个C++方法之前,用这个指针把这个指针包在同一个结构中。我不知道如何做,因为<代码>这个< /C>的语义被烘烤成C++。我缺少什么?我不相信这会起作用。在代码< Myth>od
仍将永久绑定到指向对象的原始指针。我能做的不是使用实例方法,而是执行
SomeClass::method(gc self)
。但如果可能的话,我希望避免这种情况。@您的VM是多线程的吗?执行GC时是否停止所有线程?请参阅下一篇编辑,了解这一点的重要性。