【问题标题】:Malloc works without type cast before malloc C/C++ [duplicate]Malloc 在 malloc C/C++ 之前无需类型转换即可工作 [重复]
【发布时间】:2014-01-30 10:59:27
【问题描述】:

我正在学习 malloc 函数,我读到了这个:

ptr= malloc(sizeof(int)*N)

其中N 是您要创建的整数个数。

唯一的问题是 ptr 指向什么?编译器需要知道指针指向什么,以便它可以正确地进行指针运算。换句话说,如果编译器知道 ptr 是一个指向整数的指针,它只能将 ptr++ptr=ptr+1 解释为移动到下一个整数的指令。

只要您将变量 ptr 定义为指向您要使用的变量类型的指针,此方法就可以工作。

不幸的是,这引发了一个问题,即 malloc 如何知道指针变量的类型 - 不幸的是它不知道。

要解决此问题,您可以使用TYPE cast。这种 C 语言游戏是一种将值强制为特定类型的机制。您所要做的就是将 TYPE 说明符写在值之前的括号中,即:

ptr = (*int) malloc(sizeof(int)*N)

问题

  • 我见过很多他们在 malloc 之前不使用(*int) 的地方,甚至在没有错误的情况下实现了一个链表。这是为什么呢?

  • 为什么指针需要知道除了它们指向的内存大小之外的任何东西?

【问题讨论】:

  • 您完全,无可救药地将语法与语义混淆了,并且您误解了类型的必要性。除非您实际上对指针进行指针运算,否则编译器不需要知道它的确切类型。 (更是如此,因为void * 会受到与所有其他对象指针类型之间的隐式转换。)此外,类型转换解决了问题。
  • 请注意,如果您使用的是 Visual Studio,如果您不强制返回 malloc,它会报错。忽略它。
  • @Inisheer 那完全错了,抱歉。 MSVC 也有一个 C 编译器——你应该使用它来编译 C 代码。 永远不要使用 C++ 编译器编译 C 代码。 是的,每个 C++ 编译器都会报告错误,因为 C++ 的类型系统比 C 更严格。
  • @H2CO3 是的。无论您是否仅编译为 C。它会给出视觉提示,暗示没有强制转换的 malloc 是错误的。它不一定将所有可能在 C++ 中无效的 C 代码视为错误。 malloc 是浮现在脑海中的一个,并导致许多新的 C 开发人员重新使用 malloc。

标签: c pointers memory casting malloc


【解决方案1】:

在你可以使用ptr之前,你必须声明它,你声明它的方式就是指针变成了。
malloc 返回 void * 隐式转换为任何类型。

所以,如果你必须像这样声明它

int *ptr;
ptr = malloc(sizeof(int)*N);

ptr 将指向一个整数数组,如果你声明为like

char *ptr;
ptr = malloc(sizeof(char)*N);

ptr 将指向一个 char 数组,无需强制转换。

建议不要从malloc 转换返回值。

但是我看到很多地方在 malloc 甚至我用这个做了一个链接列表并且没有错误。为什么是 那个?

因为他们(你也肯定)之前将变量声明为存储来自malloc 的返回值的指针。

为什么指针需要知道除了它们的内存大小之外的任何东西 是指什么?

因为指针也用于指针算术,这取决于它所指向的类型。

【讨论】:

  • 如果您不想考虑类型,请使用更好的 C 习惯用法ptr = malloc(N * sizeof(*ptr));,它可以分配任何类型的 N 个项目,而无需在分配时指定它(仅在声明时)。
【解决方案2】:
malloc returns pointer of type void and void type pointer is implicitly 
converted to any type so if you don't use typecast then it will also work
int *ptr;
ptr=malloc(sizeof(int)*N)

但如果你在 c++ 中使用 malloc,那么你需要进行类型转换。

【讨论】:

    【解决方案3】:

    唯一的问题是ptr指向什么?

    它指向一块大小为sizeof(int) * N的内存。

    编译器需要知道指针指向什么,才能正确进行指针运算。

    您没有在代码中执行任何指针运算,因此这不适用。从malloc() 返回void * 很好,因为void * 可以隐式转换为任何对象指针类型。

    另请注意,将返回值转换为(int *) 不会改变ptr 本身的类型。所以它没有任何好处。如果ptrvoid * 类型,那么即使你写了也不能对其进行指针运算

    void *ptr;
    ptr = (int *)malloc(sizeof(int) * N);
    

    我应该如何更好地解释这一点? 变量始终具有相同的类型,无论您为其分配哪种类型的值(例如,在这种情况下,将 void * 分配给 int * 很好,因为存在隐式转换。)

    这就是为什么你不应该转换malloc()的返回值:它没有任何好处。它无助于正确性,它可以隐藏错误,并降低可读性。

    【讨论】:

      【解决方案4】:

      在为指针分配空间之前,您需要声明指针

      int *ptr;  
      

      由于malloc 的返回类型为void *,因此可以隐式转换为任何类型。因此

      ptr= malloc(sizeof(int)*N);  
      

      将为N 整数分配空间。

      【讨论】:

        猜你喜欢
        • 2013-02-13
        • 1970-01-01
        • 2016-05-22
        • 1970-01-01
        • 2011-09-15
        相关资源
        最近更新 更多