为什么在将 void 指针转换为指向 char 指针的指针后取消引用会产生问题?

w00sung

我已经学会了指向指针的指针。我很好奇在转换“整数到指针”(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 个字节长。因此 - 当您获取5in的地址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 个字节(或系统上的任何内容)。

这是未定义的行为,这意味着标准实际上允许任何事情发生 - 但通常,您可以预期:

  1. “随机垃圾”字节
  2. 下一个局部变量的开始
  3. 访问冲突

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么将指向int的指针转换为void *但将指向函数的指针转换为bool?

来自分类Dev

C-将指针转换为指向void的指针

来自分类Dev

您可以将“函数指针指向指针”转换为void *

来自分类Dev

将 void 双指针类型转换为 void,为什么?

来自分类Dev

将指针转换为指针...指向指针?

来自分类Dev

将指针转换为void

来自分类Dev

将int指针转换为char指针

来自分类Dev

指针,将char **转换为char *

来自分类Dev

将int转换为指针-为什么先转换为long?(如p =(void *)42;)

来自分类Dev

将false转换为指针类型void *?

来自分类Dev

将 void 指针转换为动态类型

来自分类Dev

ctypes:将char的指针分解/转换为char的指针数组

来自分类Dev

将“指向const的指针”转换为“指向const VLA的指针”

来自分类Dev

允许强制转换为void(非指针),为什么?

来自分类Dev

为什么不能将函数指针转换为(void *)?

来自分类Dev

如何将void指针强制转换为函数指针

来自分类Dev

将Int转换为char *指针

来自分类Dev

如何将类型为void(*)()的指针转换为void *

来自分类Dev

什么时候在char指针上使用void指针?

来自分类Dev

将类指针转换为char指针(不安全)

来自分类Dev

如何将char指针转换为int指针

来自分类Dev

将 char 指针转换为 int 指针是如何工作的?

来自分类Dev

取消引用指向对象的 void 指针

来自分类Dev

将无符号char *缓冲区强制转换为可以接受参数的可调用void指针

来自分类Dev

转换为char指针

来自分类Dev

将void *转换为char *

来自分类Dev

为什么在指针转换中需要(void *)?

来自分类Dev

将指向成员的指针类型转换为简单的指针类型

来自分类Dev

将 void (*)() 转换为 void (*)(unsigned char)

Related 相关文章

热门标签

归档