C# 对固定块内指针所做的更改是否保留?
请查看以下c#代码:C# 对固定块内指针所做的更改是否保留?,c#,c++,pointers,unity3d,native-code,C#,C++,Pointers,Unity3d,Native Code,请查看以下c#代码: 我有来自*ptr的垃圾值。我怀疑compute分配给ptr的数组没有保留在固定块之外。是这样吗??还是因为其他问题?这是无效的代码,垃圾收集器只能更新vrt_ptr和tris_ptr变量的值。但是非托管代码使用这些指针的副本,因此副本的值不能由GC更新。因此,如果在非托管代码运行时发生垃圾收集,例如当程序中的其他线程触发收集时,则非托管代码将通过指针副本读取垃圾数据。很难诊断,它不经常发生 必须固定顶点和tris数组。在您的例子中,pinvoke marshaller已经干
我有来自*ptr的垃圾值。我怀疑
compute
分配给ptr
的数组没有保留在固定块之外。是这样吗??还是因为其他问题?这是无效的代码,垃圾收集器只能更新vrt_ptr
和tris_ptr
变量的值。但是非托管代码使用这些指针的副本,因此副本的值不能由GC更新。因此,如果在非托管代码运行时发生垃圾收集,例如当程序中的其他线程触发收集时,则非托管代码将通过指针副本读取垃圾数据。很难诊断,它不经常发生
必须固定顶点和tris数组。在您的例子中,pinvoke marshaller已经干练地完成了这项工作,只需直接传递数组而不使用fixed。修正:
相应地调整pinvoke声明,将double*替换为double[]
您现在还必须首先处理编写此代码的可能原因。在任何情况下,将int[]强制转换为double[]都是无效的,这可能是您在GC灾难发生之前得到垃圾结果的原因。如果由于某种原因无法更新tris的声明,则必须在调用之前创建一个double[.可能,
compute
返回一个指向局部变量的指针,该指针在函数返回时被销毁。但是如果不看到函数,就无法知道。@MikeSeymour局部变量的指针不会在方法返回时立即被销毁。不是吗?@ SrrimaSkTiVele:当程序离开它的范围时,本地变量将被销毁,并且它的任何指针都将指向垃圾。@ MikeSeymour似乎是代码>计算< /C> >是C++方法。我想这是一个好主意。我可能错了。如果我错了,请纠正我。我认为最好在调用compute
并将其交给它之前分配它。这样,您就可以消除虚假的ptr
,如果您稍后释放内存(以防止内存泄漏),情况会更清楚。
double* ptr;
fixed(double* vrt_ptr = &vertices[0])
{
fixed(int* tris_ptr = &tris[0])
{
ptr = compute(vrt_ptr, 5, (double*)tris_ptr, 5);
// compute() is a native C++ function
}
}
Debug.Log("Vertices Recieved: " + *ptr);
/* and so on */
double* ptr = compute(vertices, 5, tris, 5);