【问题标题】:Core dump on Pointer type-casting (int to double) in CC中指针类型转换(int to double)的核心转储
【发布时间】:2011-03-19 00:13:22
【问题描述】:

我遇到了这段代码:

void incme(double *p)
{
    *p += 1;
}

int i = 1;
incme((double *)&i);    /* WRONG */

当我尝试执行它时,我得到核心转储。这段代码有什么问题。我们可以不将 int 指针类型转换为 double 类型吗?

谢谢。

【问题讨论】:

    标签: c


    【解决方案1】:

    您不是将int 转换为double,而是将int * 转换为double *。如果sizeof(double)sizeof(int) 不一样,那就不安全了...

    即使您匹配存储大小,您希望输出是什么?浮点类型和整数往往没有任何兼容的表示形式。

    【讨论】:

      【解决方案2】:

      (int) 在 32 位硬件上通常与 4 字节对齐,而 (double) 通常需要 8 字节对齐。如果您的 i 不在 8 字节对齐的地址上,您可以期待 SIGBUS;此外,如果它是在堆栈上分配的,那么较大的(double) 可能会在incme() 返回时覆盖导致核心转储的调用帧,如果前面没有杀死它的话。

      【讨论】:

        【解决方案3】:

        您可以将任何指针从一种类型转换为任何其他类型,但这并不能使其正确。在这种情况下,如果 sizeof(double) != sizeof(int) 那么“incme”中的行很可能会写入分配给“i”整数的内存之外的内存。那么所有的赌注都结束了。

        【讨论】:

          【解决方案4】:

          类型转换和记忆重新解释是有区别的。

          您的代码将int * 类型的指针强制转换为double * 类型。这是通过使用显式强制转换来实现的。这个动作本身并不一定会导致任何问题。因此,您在问题标题中所做的假设是不正确的。您观察到的“核心转储”与演员表本身无关。

          执行转换后,您将继续取消引用结果指针并访问(修改)它指向的内存。这就是真正的问题发生的时候。代码执行数据重新解释:它尝试将int 类型的对象作为double 类型的对象进行访问。这在 C 语言中总是显式非法的。您观察到的崩溃是由这种重新解释尝试造成的。

          所以,对您的问题的简短回答是:您可以当然将指向int 对象的指针转换为double * 类型。但是您不能取消引用生成的double * 指针并访问内存,就好像它拥有一个double 对象一样。

          【讨论】:

            【解决方案5】:

            在大多数平台上,double 为 8 个字节,int 为 4,因此不,您不能将 int* 转换为 double* 并使用它

            【讨论】:

              【解决方案6】:

              一种方法是:

              int i = 1;
              double d1 = (double)i;
              double *d = &d1;
              incme(d);
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-03-11
                • 1970-01-01
                • 2020-11-17
                • 1970-01-01
                • 1970-01-01
                • 2023-04-09
                相关资源
                最近更新 更多