gpt4 book ai didi

c - 在C中增加指针地址和值

转载 作者:行者123 更新时间:2023-12-03 22:54:34 24 4
gpt4 key购买 nike

int main (void){
int num1=2;
int *pnum=NULL;
pnum=&num1;
*pnum++;
printf("%d",*pnum);

}
为什么这段代码打印的是地址,而不是值? * 不取消引用 pnum 吗?

最佳答案

查看precedence运算符的数量:后缀一元运算符比前缀一元运算符绑定(bind)更紧密,因此 *pnum++相当于*(pnum++) ,而不是 (*pnum)++ .pnum++增加指针 pnum并返回 pnum 的旧值.递增指针使其指向数组的下一个元素。任何变量都可以被视为一个元素的数组,所以 pnum指向位于 num1 的单元素数组中第一个元素之后的元素是,我称之为num1_array[1] .指向数组末尾的指针是有效的,即超过最后一个元素的一个位置。取消引用该指针是无效的:那将是数组溢出。但是计算指针是有效的。在 C 中构造一个无效指针是 undefined behavior ,即使您不取消引用它;但是这个指针是有效的。*pnum++取消引用 pnum 的旧值.因为那是指向 num1 的指针,这个表达式完全有效,它的值是num1 .此时,任何体面的编译器都会警告该值未使用。如果您没有看到此消息,请将您的编译器配置为打印更多警告:不幸的是,许多编译器默认接受错误代码而不是发出错误信号。例如,使用 GCC 或 Clang:

$ gcc -Wall -Wextra -Werror a.c
a.c: In function ‘main’:
a.c:6:5: error: value computed is not used [-Werror=unused-value]
6 | *pnum++;
| ^~~~~~~
cc1: all warnings being treated as errors
调用 printf接收参数 *pnum .我们之前看到过, pnum指向一元素数组的末尾 num1_array[1] .该指针是有效的,但由于它指向对象的末尾,因此取消引用具有未定义的行为。在实践中,这通常要么崩溃,要么打印一些恰好位于特定内存位置的垃圾值。在调试程序时,有一些工具可以帮助您使无效指针更有可能导致崩溃,而不是默默地使用垃圾值。例如,对于 GCC 或 Clang,您可以使用 AddressSanitizer :
$ export ASAN_OPTIONS=symbolize=1
$ gcc -Wall -Wextra -fsanitize=address a.c && ./a.out
a.c: In function ‘main’:
a.c:6:5: warning: value computed is not used [-Wunused-value]
6 | *pnum++;
| ^~~~~~~
=================================================================
==2498121==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff15ae3e74 at pc 0x55d593978366 bp 0x7fff15ae3e30 sp 0x7fff15ae3e20
READ of size 4 at 0x7fff15ae3e74 thread T0
#0 0x55d593978365 in main (/tmp/stackoverflow/a.out+0x1365)
#1 0x7f525a1380b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#2 0x55d59397818d in _start (/tmp/stackoverflow/a.out+0x118d)

Address 0x7fff15ae3e74 is located in stack of thread T0 at offset 36 in frame
#0 0x55d593978258 in main (/tmp/stackoverflow/a.out+0x1258)

This frame has 1 object(s):
[32, 36) 'num1' (line 3) <== Memory access at offset 36 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/tmp/stackoverflow/a.out+0x1365) in main
Shadow bytes around the buggy address:
0x100062b54770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100062b54780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100062b54790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100062b547a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100062b547b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100062b547c0: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1[04]f3
0x100062b547d0: f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100062b547e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100062b547f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100062b54800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100062b54810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==2498121==ABORTING
此跟踪告诉您:
  • 局部变量 (stack-buffer-overflow) 中存在缓冲区溢出。
  • 溢出访问是试图读取 4 个字节( READ of size 4 )。
  • 有关有问题的地址([32, 36) 'num1')的更多信息。可以看到程序在 num1 之后试图访问内存。 .
  • 有问题的指令的地址 (#0 0x55d593978365)。您可以在调试器中设置断点来检查程序可能在做什么。

  • 在大多数平台上,给定您的程序, num1stack 上的一个变量,以及 num1 的结尾是栈上前一个变量的地址。这可以是任何东西,具体取决于编译器如何访问内存的详细信息。这可能是许多事情之一是 pnum , 如果 pnumnum1碰巧在您的平台上具有相同的大小(在 32 位平台上通常是这种情况)并且编译器决定将 pnum就在 num1 之前在堆栈上(这在很大程度上取决于编译器、优化级别和程序的详细信息)。因此,您的程序打印 pnum 的地址是合理的。 : 不是因为 *pnum不知何故没有调用取消引用运算符,而是因为您的程序已使 pnum指向自己。

    关于c - 在C中增加指针地址和值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66958098/

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