using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;namespace stringAddress
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    struct A
    {
        public string str;
    }
    unsafe class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            a.str = "Hello World!";            Console.WriteLine(Marshal.SizeOf(a));
            fixed (char* p = a.str)
            {
                Console.WriteLine((int)p);//--------------------PrintOne
            }            IntPtr ptr = IntPtr.Zero;
            ptr = Marshal.AllocHGlobal(Marshal.SizeOf(a));
            Marshal.StructureToPtr(a, ptr, true);
            int* pI = (int*)ptr;
            Console.WriteLine((int)(*pI));//--------------------PrintTwo
        }
    }
}我认为PrintOne和PrintTwo的值应该是一样的,都是"Hello World!"在托管堆中的地址,也就是str这个引用的值,可是结果却不同,望高手赐教!

解决方案 »

  1.   

    希望重赏之下必有勇夫,who can help me i will give him at least 100 points
    虽然今天是愚人节,可是小弟从不愚人
      

  2.   

    http://topic.csdn.net/u/20080331/21/50caca35-fa08-4cf1-aac4-8ad819cf7d0f.html这张帖子可以作证
      

  3.   

    肯定不一样啊。你第一个指向的实际上是那个string的地址,并没有任何技术可以保证你两个东西内存中要放在一起啊。完全可以struct定义在这里,string在那里。
      

  4.   

    就算如楼上所说,那么在
    Console.WriteLine((int)(*pI));//--------------------PrintTwo 
    后我再加点代码
    char* pI = (char*)ptr;
    console.writeline(*pI);
    打印出来的也该是'H',可是实际打印出来的是 ?
    又作何解释
      

  5.   

    总算全明白了,贴点代码给大家点提示
    把Marshal.StructureToPtr(a, ptr, true); 
    下面的两行代码换成这三行
    int* pCc = (int*)ptr;
    byte* c = (byte*)(*pCc);
    Console.WriteLine((char)c[0]);
    DirectRay 兄虽然没说出具体原因,但是至少给了我提示,再加上msdn中这句解释假设 ptr 指向非托管内存块。此内存块的布局由相应的托管类 structure 描述。StructureToPtr 将字段值从结构封送到指针。假设 ptr 块包含引用字段,该字段指向当前包含“abc”的字符串缓冲区。假设托管端上相应的字段是包含“vwxyz”的字符串。如果不另行通知它,StructureToPtr 将分配一个新的非托管缓冲区来保存“vwxyz”,并将它挂钩到 ptr 块。这将丢弃旧缓冲区“abc”使之漂移而不将其释放回非托管堆。最后,您将得到一个孤立的缓冲区,它表示在代码中存在内存泄漏。如果将 fDeleteOld 参数设置为真,则 StructureToPtr 在继续为“vwxyz”分配新缓冲区之前释放保存“abc”的缓冲区。就像明白了。给dr兄30分吧,希望不要介意 ^_^
      

  6.   

    呵呵,很感谢你给了我莫大的荣誉呢~
    其实MSDN解释的时候有个问题没有说清楚,就是C#里面很多东西都是存的地址。你生成了几个不同的string,所以,地址必然和结构不一致。