【问题标题】:Invalid conversion 'void*' to 'struct*' [duplicate]无效的转换'void *'到'struct *' [重复]
【发布时间】:2019-03-15 08:17:47
【问题描述】:

我是 C 的初学者。我正在尝试解决一些问题。当我编译我的代码时,我得到了这个错误。

[错误] 从 'void*' 到 'triangle*' 的无效转换 [-fpermissive]

代码和用途解释如下。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

struct triangle
{
    int a;
    int b;
    int c;
};

typedef struct triangle triangle;

//sort_by_area() function is here
int main()
{
    int n;
    scanf("%d", &n);
    triangle *tr = malloc(n * sizeof(triangle));
    for (int i = 0; i < n; i++) {
        scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
    }
    sort_by_area(tr, n);
    for (int i = 0; i < n; i++) {
        printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
    }
    return 0;
}

如您所见,我有结构,并尝试根据输入量为其分配内存。并尝试将其用于sort_by_area 功能。但问题是triangle *tr = malloc(n * sizeof(triangle)); 行给了我上面提到的错误。

此代码也适用于在线编译器。我尝试使用默认设置在 DEV C++ 上运行此代码。我不知道版本和更改编译器的版本。我什至不知道它是否与编译器版本有关。但我想知道为什么我会收到这个错误。背后的逻辑是什么。

【问题讨论】:

  • 它是否适用于显式转换,例如triangle *tr = (triangle*)malloc(n * sizeof(triangle));
  • C 和 C++ 是两种非常不同的语言,具有非常不同的行为和规则。请仅使用您实际编程的语言的语言标签。
  • @Yksisarvinen 他收到错误的原因是因为他使用的是 C++ 编译器。
  • 这意味着您正在使用 C++ 编译器来编译 C 代码。不被禁止,但 C 和 C++ 之间的一个不兼容是 C 允许从 void * 隐式转换到其他指针类型,而 C++ 不允许。阅读编译器套件的文档,了解如何将代码编译为 C。对于某些编译器套件,您可能需要使用不同的命令/驱动程序。
  • @ibrahimG。 - 它可能有效,但这也意味着您的编译器是 C++ 编译器。 Blaze 的方法在 C 中是不好的做法。如果您打算用 C 编程,更好的解决方案是使用 C 编译器。

标签: c struct type-conversion malloc


【解决方案1】:

这看起来像 C 代码,但您正在使用 C++ 编译器进行编译。因此,它在您提到的那一行抱怨,因为malloc 返回void *,但您将结果分配给triangle *

在 C++ 中,为此需要显式转换。在 C 中,void * 可以隐式转换为任何对象指针类型或从任何对象指针类型转换。

由于这似乎是 C 代码而不是 C++ 代码,因此您应该使用 C 编译器进行编译。

【讨论】:

  • 我明白了,这真的很有帮助。谢谢。
【解决方案2】:

您将此程序编译为 C++ 程序,并且在 C++ 中不允许这种隐式转换。

据我所知,开发 C++ 使用 MinGW,您可以使用 -xc 选项将程序编译为 C 程序或设置 -> 语言标准 -> 并选择所需的语言标准

【讨论】:

    【解决方案3】:

    代码看起来像 C 代码,但您使用 C++ 编译器编译它。

    • 确保文件具有适当的 C++ 扩展名(不是 .c 扩展名)。

    • malloc() 默认返回(void *) 指针,因此您必须在代码中将(void *) 显式转换为(triangle *)

    • 但是,如果您正在编写 C++ 代码,那么我建议不要使用 malloc 和 free,而是尝试在 C++ 中使用“new”运算符,因为在实例化对象时它也会调用构造函数(与 malloc 不同)。

    所以为了避免复杂性,在 C++ 中使用 new 和 delete。


    C 中的代码应如下所示(文件 a.c)
    编译使用:gcc a.c -o a.o
    使用 ./a.o

    运行


    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    struct triangle {
      int a;
      int b;
      int c;
    };
    
    typedef struct triangle triangle;
    
    int main() {
      int n;
      scanf("%d", &n);
      triangle *tr = (triangle *)malloc(n * sizeof(triangle));
      for (int i = 0; i < n; i++) {
        scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
      }
      //sort_by_area(tr, n);
      for (int i = 0; i < n; i++) {
        printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
      }
      free(tr);
      return 0;
    }
    


    C++ 中的相同代码看起来像(文件 a.cpp)
    编译使用:g++ a.cpp -o a.o
    运行使用:./a.o

    #include <iostream>
    using namespace std;
    struct triangle {
      int a;
      int b;
      int c;
    };
    
    int main() {
      int n;
      cin >> n;
      triangle *tr = new triangle[n];
      for (int i = 0; i < n; i++) {
        cin >> tr[i].a >> tr[i].b >> tr[i].c;
      }
      // sort_by_area(tr, n);
      for (int i = 0; i < n; i++) {
        cout << tr[i].a << " " << tr[i].b << " " << tr[i].c << "\n";
      }
      delete [] tr;
      return 0;
    }
    

    【讨论】:

      【解决方案4】:
      triangle *tr = (triangle*)malloc(n * sizeof(triangle));
      

      如上所示更改该行。 malloc 返回通用指针,因此您需要将其显式类型转换为所需的指针。

      Refer this

      【讨论】:

      • 不必要地覆盖类型系统是可恶的,并且没有必要将void* 转换为不同的数据指针类型。另外,避免sizeof(TYPE)
      • 他应该使用编写程序的语言的编译器进行编译。
      猜你喜欢
      • 2023-03-16
      • 1970-01-01
      • 2017-06-30
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多