【问题标题】:dereferencing void pointers with casting使用强制转换取消引用 void 指针
【发布时间】:2015-10-05 09:38:47
【问题描述】:

我正在尝试使用 void 指针,但遇到了以下问题。当我编译以下代码时一切正常,但是当我在我的机器上运行它时,它不会给我结果而是出现提示 The program has stop working (https://drive.google.com/file/d/0B1mLcnk8kTFUeEtmYnlOaWJ6T3c/view?usp=sharing) ,我不知道后面发生了什么场景,关于取消引用void指针是否有任何问题。

如果我使用注释代码而不是原始代码,它将起作用。

 #include<stdio.h>
 int main()
 {
     void* ptr;
     int dupe = 5;
     *(int* )ptr = dupe;  // ptr = &dupe;
      printf("The value at ptr is %3d",*(int* )ptr);
 }

我在 CodeBlocks 上使用 gcc。

【问题讨论】:

  • 在第 6 行,您取消引用了一个无处指向的指针(它包含垃圾地址),并尝试将 dupe 的值放在那里(即无处)。
  • 请注意*(int* )ptr = dupe; 不是ptr = &amp;dupe;。第二个赋值绝对有效,不会导致未定义的行为。
  • 是否有可能在某些编译后,分配给它的垃圾地址是有效的?
  • "分配给它的垃圾地址" -- 它没有分配,它是堆栈上的任何垃圾。几乎可以肯定是 0,这是一个受保护的页面,因此您会遇到访问冲突。
  • 如果你仍然有问题,ptr = &amp;dupe; 就像在明信片上写下你朋友的地址,*(int *)ptr = dupe; 就像在明信片上乱涂乱画,然后去你朋友家告诉他在您写在这张明信片上的地点与您见面

标签: c pointers void-pointers


【解决方案1】:

这里你试图取消引用一个指针而不给它分配内存。这会导致segmentation faultundefined behaviour

int main(int argc, char *argv[])
{
    void* ptr;
    int dupe = 5;
    ptr = malloc(sizeof(dupe)); /* alloc memory for ptr */
    *(int* )ptr = dupe;
    printf("The value at ptr is %3d",*(int* )ptr);
    free(ptr);
    return 0;

}

如果您不打算分配内存,那么只需在您的代码中将*(int* )ptr = dupe; 替换为ptr = &amp;dupe,因为现在ptr 将指向变量dupe 的有效内存位置。
有关未定义行为的更多详细信息,请参阅this

【讨论】:

  • (int *)ptr 使用未初始化的指针值导致 UB,即使之后没有取消引用
  • 那么,为什么在我使用第 6 行的注释代码而不是原始代码而不使用 malloc() 时它会起作用?
  • @BigO 其他代码不同。不同的代码做不同的事情
  • @BigO ptr = &amp;dupe 甚至不像*(int* )ptr = dupe
  • 我知道他们俩一点都不像,但评论不是为了联系他们,我只是想知道这个声明是做什么来使程序正常工作的。
【解决方案2】:
6.       *(int* )ptr = dupe;  // ptr = &dupe;

指针 ptr 未指向有效的内存位置。你在评论里写的,就是你应该做的。

语句ptr = &amp;dupe 将使ptr 指向变量dupe 的内存位置。

【讨论】:

  • 发现您的答案很有用,但唉!回购问题要投票。
【解决方案3】:
1. void* ptr; --->ptr is a void pointer that means it can hold an address of any data type, but currently it is not pointing to any address.
2. *(int* )ptr = dupe ---> ptr point to no where and you are trying to put a value which is not valid.
3. ptr = &dupe; --> in this case ptr will point to address of dump which is a valid one.

【讨论】:

    【解决方案4】:

    一个指针int *ptr,通常是一个地址值,就像一个盒子的编号。这里int是盒子类型,它暗示这个盒子是为放置int而设计的。当然,您也可以小心地投射它以适应其他类型的内容,例如(otherKindType*)ptr
    当尝试使用*ptr = someValue 来引用一个指针时,比如将对象放入盒子中,您应该保证它指向某个准确的位置。

    代码1(可以工作):

    #include<stdio.h>
    int main()
    {
        void* ptr; // ptr is a pointer, it should point to somewhere 
        int dupe = 5; // a box (named dupe) fitted for int which hold 5
        ptr = &dupe; // ptr points to that box named dupe
        printf("The value at ptr is %3d",*(int* )ptr); // get content inside the box
    }
    

    代码2(不工作):

    #include<stdio.h>
    int main()
    {
        void* ptr;// pointer, point to a random place
        int dupe = 5;
        *(int* )ptr = dupe; // To put 5 to the box that pointed by ptr
                            // But now, ptr still points to a random place
                            // oops! To write to a random box is dangerous!
                            // It will cause error like `BUS error`
                            // Sometimes, to read a random box can output wired value.
        printf("The value at ptr is %3d",*(int* )ptr);
    }
    

    Code3(可以工作):

    #include<stdio.h>
    int main()
    {
        void* ptr;
        int dupe = 5; 
    
        int new_box;//added         
        ptr = &new_box;//added, now ptr points to new_box        
    
        *(int* )ptr = dupe; // To put 5(content of dupe) to the box that pointed by ptr
                            // That is to put 5 to new_box
        printf("The value at ptr is %3d",*(int* )ptr); // get content inside the box
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-03
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-23
      • 2011-06-17
      相关资源
      最近更新 更多