【问题标题】:How to know the memory adress of elements in list c#如何知道列表c#中元素的内存地址
【发布时间】:2011-10-20 23:48:48
【问题描述】:

我有:

        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

如何打印每个数字的内存位置,我尝试了&num,但出现错误。

【问题讨论】:

  • 这不是 c# 的部分意义吗?因为内存管理主要是为您处理的,所以您不应该为实际的内存地址而烦恼?您需要这些地址是否有特定原因?
  • C# memory address and variable 的可能重复项
  • 好吧,我需要做一些连续的内存传递,并告诉其他一些函数从哪里开始指向
  • @cMinor 如果这是用于互操作,那么您应该编组数组 / 项目而不是使用 unsafe

标签: c# list


【解决方案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);

【讨论】:

    【解决方案2】:

    不使用内存位置还有另一个原因。如果您将项目添加到列表中,则用于存储列表项目的内部数组可能会调整大小,即将创建一个具有前一个大小两倍的新数组,并将项目复制到新数组中。但是,我上一篇文章中显示的参考技巧仍然有效。

    【讨论】:

      【解决方案3】:

      现在有一种方法可以在 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;
      

      【讨论】:

        【解决方案4】:

        您必须使用unsafe 代码才能使其正常工作。 See here 了解更多详情。

        【讨论】:

          猜你喜欢
          • 2016-10-30
          • 1970-01-01
          • 2021-01-05
          • 2011-05-07
          • 2012-10-03
          • 1970-01-01
          • 2018-05-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多