为了深入研究内存的分配和存储方式,我编写了一个可以扫描内存地址空间,查找值并写出新值的应用程序。
我开发了一个示例应用程序,其最终目标是能够以编程方式定位我的数组,并用新的数字序列覆盖它。在这种情况下,我创建了一个具有5个元素的单维数组,例如
int[] array = new int[] {8,7,6,5,4};
我运行了我的应用程序并搜索了上面五个数字的序列。我正在寻找4到8之间的任何值,连续5个数字。不幸的是,我在阵列中的序列号匹配了数百个结果,因为在许多情况下,数字4到8没有特定的顺序在内存中碰巧彼此相邻。
有没有办法区分内存中的一组数字,代表一个数组,而不仅仅是彼此相邻的整数?有没有办法知道,如果我找到一个特定的值,那么匹配值继续它是一个数组的那个?
我会假设当我声明int[] array
时,它指向我的数组的第一个地址,这将为数组中存在的内容提供某种元数据,例如。
0x123456789 meta-data, 5 - 32 bit integers 0x123456789 + 32 "8" 0x123456789 + 64 "7" 0x123456789 + 96 "6" 0x123456789 + 128 "5" 0x123456789 + 160 "4"
我离开基地了吗?
答案 0 :(得分:5)
Debug + Windows + Memory + Memory 1,将Address字段设置为“array”。当您将视图切换为“4字节整数”时,您会看到这一点:
0x018416BC 6feb2c84 00000005 00000008 00000007 00000006 00000005 00000004
第一个地址是垃圾收集堆中对象的地址,以及处于负偏移量(syncblk索引)的对象头部分。你不能猜测这个值,GC移动它。第二个十六进制数是数组类型的“类型句柄”(也就是方法表指针)。您无法猜测此值,类型句柄是由CLR按需创建的。第3个数字是数组长度。其余的是数组元素值。
在没有调试器的情况下在运行时可靠地找到此数组的几率非常低。尝试没有多大意义。
答案 1 :(得分:0)
别。数组存储在堆上,由于垃圾回收而需要重新定位。你必须使用fixed,如果你需要确保移动内存,你可以使用,但只能非常小心。
如果您使用的是高性能阵列,请使用stackalloc并使用您的代码方案。
答案 2 :(得分:0)
内存并不总是连续存储。如果你能确保它是可能的,那么你所要求的就是可能的。
答案 3 :(得分:0)
我不完全确切,但this article似乎暗示你可以获得一个指向你的数组的指针,我认为你可以用它确定实际的地址。
答案 4 :(得分:0)
虽然我看到你正在使用C#,并且可能是.NET,但大多数问题都是关于内存的非常笼统的问题。请记住,从最普遍的意义上讲,无论该内存是否包含数组,字符串或代码,所有内存都只是位。
考虑到这一点,除非你能找到当前平台分配不同数据类型的方式的迹象,否则包含数组,字符串或代码的内存之间没有区别。
另外,我不会对数组是否“指向”数组中的第一项做出任何假设。也许其他人可以专门解决这个问题,但我会假设涉及某种标题。