我已经学会了指向指针的指针。我很好奇在转换“整数到指针”(char*)(int)
和“空指针到字符指针的指针”之后取消引用。(char**)(void*)
现在,当我想取消对指向 char 指针的指针的 void 指针的引用时,会出现一些问题。(char**)(void*)
我尝试了2个案例。
整数到指针 (char*)(int)
#include <stdio.h>
int main()
{
int a = 10;
int b;
void* ptr = &a;
b = ptr;
printf("%d\n", *(unsigned int*)b);
printf("%d\n", *(void**)(b));
printf("%p\n", *(char**)(b));
return 0;
}
*(unsigned int*)b
*(void**)(b)
*(char**)(b)**
这三个读取地址中的10。
但是下面的代码有问题。(请观看ptr_speacial)“指向 char 指针的指针的空指针。”(char**)(void*)
#include <stdio.h>
int main()
{
int arr[5] = { 1,2,3,4,5 };
char arr2[5] = { 1,2,3,4,5 };
void* ptr_arr;
void* ptr_arr2;
void* ptr_special;
ptr_arr = arr;
ptr_arr2 = arr2;
ptr_special = (char*)ptr_arr2 + 4;
printf("address : %p: value : %d\n", ptr_special, *(char**)ptr_special);
printf("%d\n", *(char**)ptr_arr);
return 0;
}
*(char**)ptr_special
没有读到地址中的 5 而是 -858993659
我不确定,但我认为这是溢出问题。在这种情况下发生了什么?请帮我!
看看这个:
#include <stdio.h>
int main()
{
char arr2[] = { 1,2,3,4,5 };
char arr3[] = { 1,2,3,4,5 };
void* ptr_special2 = arr2 + 4;
void* ptr_special3 = arr3 + 4;
printf("address : %p: value : %d\n", ptr_special2, *(char**)ptr_special2);
printf("address : %p: value : %d\n", ptr_special2, *(char**)ptr_special3);
return 0;
}
输出(可能会有所不同):
address : 0x7ffc5841755a: value : 50462981
address : 0x7ffc5841755a: value : 1074892805
现在试试这个:
char arr2[] = { 1,2,3,4,5,0,0,0 };
char arr3[] = { 1,2,3,4,5,1,0,0 };
输出:
address : 0x7fffecb291fc: value : 5
address : 0x7fffecb291fc: value : 261
在阅读之前尝试弄清楚发生了什么......
在我的系统上,“指向一个字符的指针的指针”是 4 个字节长。因此 - 当您获取5
in的地址arr2
,将其char**
强制转换为 a并取消引用它时 - 系统读取 4 个字节,从5
.
在 中arr2
,这 4 个字节是5 0 0 0
,在 little-endian 系统中被解释为 5。
在 中arr3
,这 4 个字节是5 1 0 0
,在小端系统中被解释为 5 + 256 = 261。
在您的代码中, 后面的三个字节5
是未知的。你不知道编译器在那里放置了什么(如果有的话)。您正在读取超出数组末尾的内容,因为您试图sizeof(char**)
从在该地址只有 1 个有效字节的数组中读取 4 个字节(或系统上的任何内容)。
这是未定义的行为,这意味着标准实际上允许任何事情发生 - 但通常,您可以预期:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句