我有:
List<double> w = new List<double>();
w.Add(1);
w.Add(2);
w.Add(1);
w.Add(4);
w.Add(5);
w.Add(1);
foreach (double num in w)
{
Console.WriteLine(num);
}
写哪
1 2 1 4 5 1
如何打印每个号码的内存位置,我试过&amp; num,但得到错误。
答案 0 :(得分:1)
现在有办法在c#中获取内存位置。内存地址是.NET Framework中的禁忌,因为垃圾收集器可能会重新排列堆上的内容。
您可以使用的所有内容都是列表索引。你可以重新设计你的循环:
for (i = 0; i < w.Count; i++) {
Console.WriteLine(w[i]);
}
如果您想直接引用某个项目,请使用以下引用类型:
class MyDouble
{
Public double Num { get; set; }
}
然后声明:
var w = new List<MyDouble>();
w.Add(new MyDouble{Num = 1});
var referenced = new MyDouble{Num = 2};
w.Add(referenced);
a.Add(...);
Console.WriteLine(referenced.Num);
referenced.Num = 7;
答案 1 :(得分:1)
为什么不使用内存位置还有另一个原因。如果将项添加到列表中,则可能会调整用于存储列表项的内部数组,即将创建具有前一个的双倍大小的新数组,并将项复制到新数组中。然而,我在上一篇文章中显示的参考技巧仍然有用。
答案 2 :(得分:1)
如果您正在使用P / Invoke并且想要将元素列表传递给C函数,则在大多数情况下您可以使用属性来完成工作。例如
[DllImport("x.dll")]
extern void PassDoubleArray([MarshalAs(UnmanagedType.LPArray)]Double[] array);
如果你有一些更复杂的东西并且需要手动完成,那么Marshal
类就拥有了完成它所需的大部分工作。
首先,使用Marshal.AllocHGlobal
分配一些非托管内存 - 足以存储您的对象或数组,这将为您提供IntPtr
。您可以使用Marshal.Copy.
将非原语复制到非托管内存和从非托管内存中复制.NET原语,创建结构并使用Marshal.StructureToPtr
为其获取IntPtr。完成非托管内存后,拨打Marshal.FreeHGlobal
即可将其释放。
例如,这将相当于上述属性,但更加冗长。
[DllImport("x.dll")]
extern void PassDoubleArray(IntPtr array);
List<Double> vals = new List<Double>() { ... }
IntPtr unmanaged = Marshal.AllocHGlobal(vals.Length * sizeof(Double));
Marshal.Copy(vals.ToArray(), 0, unmanaged, vals.Length);
PassDoubleArray(unmanaged);
Marshal.FreeHGlobal(unmanaged);
答案 3 :(得分:0)
您必须使用unsafe
代码才能实现此目的。 See here了解更多详情。