Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 理解内存地址的值_C_Memory_Stack_Buffer Overflow - Fatal编程技术网

C 理解内存地址的值

C 理解内存地址的值,c,memory,stack,buffer-overflow,C,Memory,Stack,Buffer Overflow,出于好奇,我编写了一个非常简单的程序,读取单个元素数组前后的前1000个字节,看看我会得到什么值,以及如何利用它们 包括 int main{ charmem[1]; printf\n\t继续…\n\t%lld到%lld\n\n,mem,mem+1000; forint i=0;i=0;i-; printf%lld,*mem-i; printf\n\n----结束---\n\n; 返回0; } 选择%lld的原因是我有一个模糊的想法,即64位系统将有64位地址,因此long-long可能适合64

出于好奇,我编写了一个非常简单的程序,读取单个元素数组前后的前1000个字节,看看我会得到什么值,以及如何利用它们

包括 int main{ charmem[1]; printf\n\t继续…\n\t%lld到%lld\n\n,mem,mem+1000; forint i=0;i=0;i-; printf%lld,*mem-i; printf\n\n----结束---\n\n; 返回0; } 选择%lld的原因是我有一个模糊的想法,即64位系统将有64位地址,因此long-long可能适合64位int

我没有使用%d,因为由于int太小,这会给我-ve个值,%x或%o也会对超出无符号int大小的值发疯-例如,我会得到ffff。。。其中int将读取-ve值

我知道就C标准而言,这基本上是U.B.,但没有什么是真正随机的,因此我想知道可能的原因:

有些值,如127、0,会持续重复 显示的大多数值是8/10位,这些数字是固定的:4294967。。。 一些明显随机的2或3位数的值在这一大堆数字之间浮动,比如123、18、55、96。。。 我不是在问为什么会出现这些精确的值,这是不可能回答的,我是在问为什么0,8-10位数字和7个常用数字的一般模式?一些看起来正常的2-3位数的值出现了,如何理解这些值

此外,仅在MacOSX上运行此命令还没有尝试Windows,并且在使用%c时,在“查找前进”时,它会返回实际字符,如下所示:

executable_path=./memdump./memdumpTERM_PROGRAM=Apple_TerminalSHELL=/bin/bashTERM=xterm-256colorTMPDIR=/var/folders...
为什么?

printf说明符%lld需要一个long-long-as参数。如果你提供了一个较短的变量,就像你所做的那样,你只设置了这个参数的一部分,并导致UB,除了访问数组时导致的UB之外,是的,我知道UB是UB,并且没有其他形式的UB,但是我想解释为什么你会得到你得到的值。在AMD64上,值的上32位可能与之前使用的寄存器设置的程序的某个随机部分相同,char参数仅更改下32位部分。超出int范围的每个值都是由于此错误造成的。 mem[i]是一个char,然后被提升为int。因此,通常不会得到int范围内的值,但不会以这种方式得到char范围内的值

如果你想做这个实验,请使用正确的格式说明符,我建议你使用十六进制格式说明符。使用未签名字符也会更聪明。它仍然是UB,因为它访问内存超出范围,但您更可能打印内存中实际存储的内容


你可以使用[]运算符的负值,当你有一个指针指向数组的中间或末尾,而负值仍然在数组中时,这是很好的定义。您的情况并非如此,因为它已不在阵列中,但仍能正常工作。您可以将两个循环合并为一个循环。

非常感谢您的详细回答!我非常感激。问题-除了%x之外,还有哪些格式说明符是合适的?如果我想读十进制呢?%hhu是否合适?%hhu用于未签名字符,这对于printf来说没有意义,因为所有小于int的字符都会升级为int。您必须使用%u。当然,尽管升级过程中存在一些问题,但%hhu是合适的。这正是重点。甚至该标准也明确规定:指定以下d、i、o、u、x或x转换说明符应用于有符号字符或无符号字符参数该参数将根据整数升迁进行升迁,但其值应在打印前转换为有符号字符或无符号字符;或者后面的n个转换说明符应用于指向有符号字符参数的指针@AnttiHaapala编译器建议使用%hhn,使用%hhu会产生奇怪的结果…@user13863346%hhn???我猜你没有取消对指针的引用?评论不用于扩展讨论;这段对话已经结束。