C编程:strtol()和处理NUL字节

时间:2012-06-12 20:50:02

标签: c char hex

说我有一个地址和偏移量,如:

   char* base_addr = "\x00\x00\x00\xb7";
   char* addr_offset = (user input);

我希望将base_addr和addr_offset一起添加。我是否必须编写自己的strtol()函数,该函数不会在NUL处终止,或者是否有其他方法可以成功添加这两个地址?

编辑:

忘了说这是Linux x86。

1 个答案:

答案 0 :(得分:0)

base_addr实际上是一个32位整数值,恰好是使用字节常量进行硬编码的。您只需将指针类型强制转换为unsigned long,然后在用户输入的字符串上调用strtol(),并将两者相加。

使用字符串硬编码指针是很蹩脚的。首先,C将在字符串的末尾添加一个NUL字节,所以现在你的32位值占用5个字节,并且添加了填充字节,你最终可能会使用8个字节来存储你的指针,正好是所需的两倍。最好这样做:

char base_addr[] = {'\x00', '\x00', '\x00', '\xb7'};

更好地说出你的意思,只要编译器允许你进行类型转换:

unsigned char *base_addr = (unsigned char *)0xb7000000;

我刚刚检查过,GCC允许您在没有错误或警告的情况下执行上述操作。

编辑:哦,好吧,真正的问题是如何访问整数值内的字节。

你应该能够通过弄乱指针来做到这一点:

unsigned long base_adr = 0xb700000000;
unsigned char *p = (unsigned char *)&base_adr;

上述技巧适用于整数类型。另一种方法是使用C联盟:

typedef union
{
    char bytes[4];
    unsigned long n;
    unsigned char *ptr;
} ADR_WINDOW;

ADR_WINDOW x;

x.n = 0xb700000000;
assert(x.bytes[3] == 0xb7); // on a little-endian computer
assert(x.bytes[0] == 0xb7); // on a big-endian computer

联合技巧适用于任何类型,并且是查看浮点值内部位的唯一可移植方法。