我有一个pintool应用程序,它将应用程序访问的内存地址存储在一个文件中。这些地址是十六进制形式。如果我以字符串的形式写这些地址,它将需要大量的存储空间(接近300GB)。编写这么大的文件也会花费大量的时间。所以我想到了另一种减少使用存储量的方法。
十六进制地址的每个字符代表4位,每个ASCII字符为8位。所以我想用一个ASCII字符表示两个十六进制字符。
例如: 如果我的十六进制地址是 0x26234B 那么相应的转换后的ASCII地址将是& #K (忽略0x,因为我知道所有地址都是十六进制的。)
我想知道有没有其他更有效的方法来实现这一点,这需要更少的存储空间。
注意:我正在使用c ++
答案 0 :(得分:0)
这是一个好的开始。如果您真的想要更进一步,可以考虑使用zip库或霍夫曼编码来压缩数据。
答案 1 :(得分:0)
假设您的地址是64位指针,并且这种表示对您的平台是明智的,您可以将它们存储为64位整数。例如,您列出0x1234567890abcdef
,它可以存储为四个字节:
12 34 56 78 90 ab cd ef
(your pointer, stored in 8 bytes.)
或相同,但向后,取决于您选择的endianness。具体来说,您应该阅读this。
我们甚至可以在某种程度上独立于平台:uintptr_t
是无符号整数类型,与指针的宽度相同(假设一个存在,它通常会这样做,但它不是一个确定的东西),和sizeof(our_pointer)
,它给出了指针的字节大小。我们可以通过以下方式得到上述字节:
0x0026234b
)在代码中:
unsigned char buffer[sizeof(YourPointerType)];
for(unsigned int i = 0; i < sizeof(YourPointerType); ++i) {
buffer[i] = (
(reinterpret_cast<uintptr_t>(your_pointer) >> (sizeof(YourPointerType) - i - 1))
& 0xff
);
}
一些注意事项:
>> 0
。我怀疑这可能是未定义的行为,你需要一个if-case来处理它。uintptr_t
不会存在。)它不会像在32位平台上那样在64位上做同样的事情,因为它们有不同的指针大小。 (或者您遇到的任何其他指针大小的平台。)可能有一个图书馆会为你做这件事。 (struct
,在Python中,这样做。)
以上是一个大端编码器。或者,您可以写出小端 - 维基百科的文章详细说明了差异。
最后,您可以将指针强制转换为指向unsigned char *
的指针,并将其写入。 (即,将指针的实际内存转储到文件中。)但这更依赖于平台。
如果您需要更多空间,请通过gzip
运行。