Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C语言中不必要的指针强制转换_C++_C_Pointers - Fatal编程技术网

C++ C语言中不必要的指针强制转换

C++ C语言中不必要的指针强制转换,c++,c,pointers,C++,C,Pointers,我在这个帖子上得到了对我答案的评论: 简而言之,我有这样的代码: int * somefunc (void) { int * temp = (int*) malloc (sizeof (int)); temp[0] = 0; return temp; } 我得到这样的评论: 我能不能说,请不要投 malloc的返回值?事实并非如此 必需,并且可以隐藏错误 我同意C++中不需要强制转换。C++中强制转换,所以我通常添加它们,以防有一天我必须在C++中输入代码。 然而,我想知道这样的

我在这个帖子上得到了对我答案的评论:

简而言之,我有这样的代码:

int * somefunc (void)
{
  int * temp = (int*) malloc (sizeof (int));
  temp[0] = 0;
  return temp;
}
我得到这样的评论:

我能不能说,请不要投 malloc的返回值?事实并非如此 必需,并且可以隐藏错误

<>我同意C++中不需要强制转换。C++中强制转换,所以我通常添加它们,以防有一天我必须在C++中输入代码。 然而,我想知道这样的强制转换如何隐藏错误。有什么想法吗

编辑:
似乎双方都有非常好和有效的论点。谢谢大家发帖。

铸造一个返回(void*)而不是(int*)的函数是无害的:您铸造的是一种指向另一种类型的指针


将返回整数的函数转换为指针很可能是不正确的。如果您没有显式地强制转换它,编译器会标记它。

似乎很适合我发布一个答案,因为我留下了注释:p

基本上,如果忘记包含
stdlib.h
,编译器将假定
malloc
返回
int
。没有施法,你会得到警告。有了演员你就不会了

因此,通过施放,你将一无所获,并冒着压制合法警告的风险

关于这方面的文章很多,快速的谷歌搜索会找到更详细的解释

编辑 有人认为

TYPE * p;
p = (TYPE *)malloc(n*sizeof(TYPE));
当您意外地没有分配足够的内存时,这一点很明显,比如说,您认为
p
TYPe
而不是
TYPe
,因此我们应该使用malloc,因为这种方法的优点覆盖了意外抑制编译器警告的较小成本

我想指出两点:

  • 您应该编写
    p=malloc(sizeof(*p)*n)
    始终确保分配正确的空间量
  • 使用上述方法,如果更改
    p
    的类型,您需要在3个位置进行更改:一次在声明中,一次在
    malloc
    中,一次在cast中
  • 简而言之,我个人仍然认为没有必要强制转换malloc的返回值,这当然不是最佳实践。

    一个可能的错误(取决于您是否真的想要)是使用一个大小刻度进行mallocing,并分配给不同类型的指针。例如:

    int *temp = (int *)malloc(sizeof(double));
    

    在某些情况下,您可能希望这样做,但我怀疑这种情况很少见。

    嗯,我认为恰恰相反——总是直接将其转换为所需的类型

    > P>另一方面,如果你需要将代码移植到C++,最好使用“新”操作符。

    实际上,一个演员可以隐藏错误的唯一方法是,如果你从一个数据类型转换为更小的数据类型和丢失的数据,或者如果你把梨转换成苹果。以以下为例:

    int int_array[10];
    /* initialize array */
    int *p = &(int_array[3]);
    short *sp = (short *)p;
    short my_val = *sp;
    
    在这种情况下,转换为short将从int中删除一些数据。在这种情况下:

    struct {
        /* something */
    } my_struct[100];
    
    int my_int_array[100];
    /* initialize array */
    struct my_struct *p = &(my_int_array[99]);
    
    在这种情况下,您最终会指向错误类型的数据,甚至指向无效内存


    但总的来说,如果你知道自己在做什么,就可以做演员。当您从malloc获取内存时更是如此,它恰好返回一个空指针,除非您强制转换它,否则您根本无法使用它,并且如果您强制转换到左值(赋值左侧的值)无论如何都无法接受的对象,大多数编译器会警告您。

    我认为您应该将强制转换放入。考虑类型有三个位置:

    T1 *p;
    p = (T2*) malloc(sizeof(T3));
    
    这两行代码之间可能有很大的距离。因此,编译器最好将T1==T2。直观地验证T2==T3更容易

    如果你错过了T2的演员阵容,那么你必须希望T1==T3


    另一方面,您缺少stdlib.h参数,但我认为这不太可能是一个问题。

    它可能引入的一个错误是,如果您在64位系统上使用C(而不是C++)进行编译

    基本上,如果忘记包含stdlib.h,将应用默认的int规则。因此,编译器将愉快地假设
    malloc
    具有
    int malloc()的原型
    在许多64位系统上,int为32位,指针为64位

    哦,值被截断了,你只得到指针的32位!现在,如果您强制转换返回值
    malloc
    ,此错误将被强制转换隐藏。但如果不这样做,您将得到一个错误(性质为“无法将int转换为t*”)

    <>这当然不适用于C++,原因有2。首先,它没有默认的int规则,其次它需要强制转换


    总之,你应该只在C++代码中新的:P.

    这个问题被标记为C和C++,所以它至少有两个答案,imHo:< /P> C 啊哼。。。你想干什么就干什么

    我相信上面给出的理由“如果你不包括“stdlib”,那么你就不会得到警告”是无效的,因为人们不应该依靠这种黑客来避免忘记包括一个标题

    使您不能编写强制转换的真正原因是C编译器已经悄悄地将
    void*
    强制转换为您想要的任何指针类型,因此,自己这样做是多余和无用的

    如果您想拥有类型安全性,您可以切换到C++或编写自己的包装函数,例如:

    int * malloc_Int(size_t p_iSize) /* number of ints wanted */
    {
       return malloc(sizeof(int) * p_iSize) ;
    }
    
    C++ 有时,即使在C++中,你也必须从MalC/ReAlcC/FULL UTILS中获利。那你就得投了。但你已经知道了。和往常一样,使用static_cast()比使用C样式的cast更好

    在C中,您可以通过模板覆盖malloc(和realloc等)以实现类型安全:

    template <typename T>
    T * myMalloc(const size_t p_iSize)
    {
     return static_cast<T *>(malloc(sizeof(T) * p_iSize)) ;
    }
    
    模板
    T*myMalloc(常数大小)
    {
    返回静态(malloc(sizeof(T)*p_iSize));
    }
    
    其使用方式如下:

    int * p = myMalloc<int>(25) ;
    free(p) ;
    
    MyStruct * p2 = myMalloc<MyStruct>(12) ;
    free(p2) ;
    
    int*p=myMalloc(25);
    自由基(p);
    MyStruct*p2=myMalloc(12);
    自由(p2);
    
    下面呢
    // error: cannot convert ‘int*’ to ‘short int*’ in initialization
    short * p = myMalloc<int>(25) ;
    free(p) ;
    
    #if CPLUSPLUS
    #define MALLOC_CAST(T) (T)
    #else
    #define MALLOC_CAST(T)
    #endif
    ...
    int * p;
    p = MALLOC_CAST(int *) malloc(sizeof(int) * n);
    
    #if CPLUSPLUS
    #define MYMALLOC(T, N) static_cast<T*>(malloc(sizeof(T) * N))
    #else
    #define MYMALLOC(T, N) malloc(sizeof(T) * N)
    #endif
    ...
    int * p;
    p = MYMALLOC(int, n);
    
    int from_f(float f)
    {
        return *(int *)&f;
    }
    
    int *p = (int *)malloc(sizeof(int) * 10);