gpt4 book ai didi

c - 来自 strtol 的意外输出

转载 作者:太空狗 更新时间:2023-10-29 15:58:11 33 4
gpt4 key购买 nike

我正在尝试创建一个小程序,它接受物理内存位置并打印存储在该位置的数据。我将两个参数传递给程序 - 地址和我要打印的内存大小(以字节为单位)。

我遇到的问题是,当我传入的地址超过某个值时,strtol() 函数会传递一个无意义的值。代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <asm-generic/fcntl.h>
#include <unistd.h>

int main(int argc, char** argv)
{
unsigned int mem_address,mem_size;
int loop, i;
int *ptr, *mem_address_current;

printf("mem_addr: %s\n",argv[1]);
printf("mem_size: %s\n",argv[2]);

mem_address = strtol(argv[1], NULL, 16);
mem_size = strtol(argv[2], NULL, 16);

printf("mem_addr: %x\n",mem_address);
printf("mem_size: %x\n",mem_size);

int mem_dev = open("/dev/mem", O_RDWR);

if(mem_dev == -1)
{
printf("No worky\n");
exit(1);
}

int alloc_mem_size, page_mask, page_size;
void *mem_pointer, *virt_addr;

page_size = sysconf(_SC_PAGESIZE);
alloc_mem_size = (((mem_size / page_size) + 1) * page_size);
page_mask = (page_size - 1);

mem_pointer = mmap(NULL,
alloc_mem_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
mem_dev,
(mem_address & ~page_mask)
);


if(mem_pointer == MAP_FAILED)
{
printf("no_worky2\n");
exit(1) ;
}

virt_addr = (mem_pointer + (mem_address & page_mask));
ptr = mem_pointer;
loop = (mem_size/16) + 1;
for(i = 0;i < loop;i++) {
printf("%#x: %08x %08x %08x %08x\n", ptr, *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3));
ptr = ptr + 4;
}

return 0;


}

如果我运行以下命令,我会得到预期的值。

root@p1025:~# ./test_prog_ppc 0100000 16                                                                                              
mem_addr: 0100000
mem_size: 16
mem_addr: 100000
mem_size: 16
0x48001000: 38210020 4e800020 9421ffe0 7c0802a6
0x48001010: 2c050000 bf410008 7c7e1b78 90010024

但是,如果我更改输入地址,值将与预期不同:

root@p1025:~# ./test_prog_ppc ffee0000 16
mem_addr: ffee0000
mem_size: 16
mem_addr: 7fffffff
mem_size: 16

关于为什么会发生这种情况有什么想法吗?

感谢您的帮助。

最佳答案

strtol() 返回一个(带符号的)long。根据您的输入,您正在尝试解析无符号 32 位数字,因此如果 long 在您的系统上是 32 位,则 strtol() 将超出范围。在这种情况下,它将返回 LONG_MAX,在您的系统上显示为 0x7FFFFFFF

您应该改用 strtoul(),并将结果存储在 unsigned long 中,而不是像现在这样存储在 unsigned int 中,因为虽然 long 保证至少是 32 位,但 int 不是。

此外,您确实应该将真实指针的地址作为第二个参数传递给 strtol() 和 friend ,并使用它来检查错误。现在,如果 argv[1]argv[2] 不是以数字开头,您将无法区分输入是否错误,或者输入是否为合法的零。

关于c - 来自 strtol 的意外输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23639990/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com