3

I'm beginner in C. I'm trying to practice with solving some problems. And I'm getting this error when I compile my code.

[Error] invalid conversion from 'void*' to 'triangle*' [-fpermissive]

The code and purpose is explained below.

#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;
}

As you can see I have structure and I tried to allocate memory for it with the quantity of input. And try to use it for sort_by_area function. But the problem is triangle *tr = malloc(n * sizeof(triangle)); line gives me the error mentioned above.

Also this code is working for online compilers. I tried to run this code on DEV C++ with default settings. I don't know about the versions and changing the versions of my compiler. I don't even know whether it is about the compiler version. But I am wondering why I'm getting this error. What is the logic behind.

dbush
  • 205,898
  • 23
  • 218
  • 273
ibrahimG.
  • 73
  • 2
  • 8
  • 1
    Does it work with an explicit cast, like `triangle *tr = (triangle*)malloc(n * sizeof(triangle));`? – Blaze Oct 10 '18 at 12:08
  • 7
    C and C++ are two *very* different languages with very different behavior and rules. Please use only the language-tag of the language you're actually program in. – Some programmer dude Oct 10 '18 at 12:08
  • 1
    @Yksisarvinen The reason he's getting the error is because he's using a C++ compiler. – David G Oct 10 '18 at 12:09
  • @Yksisarvinen Considering the error, I'd say it's the opposite. – Some programmer dude Oct 10 '18 at 12:09
  • `#ifdef __cplusplus` / `#error wrong compiler` / `#endif` – pmg Oct 10 '18 at 12:09
  • 1
    It means that you're using a C++ compiler to compile C code. Not forbidden, but one incompatibility between C and C++ is that C allows implicit conversion from `void *` to other pointer types, and C++ doesn't. Read documentation for your compiler suite to work out how to compile your code as C. With some compiler suites you may need to use a different command/driver. – Peter Oct 10 '18 at 12:11
  • @Blaze It work, amazing. – ibrahimG. Oct 10 '18 at 12:12
  • 2
    @ibrahimG. - it may have worked, but it also means your compiler is a C++ compiler. Blaze's approach is bad practice in C. Better solution, if you intend to program in C, is to use a C compiler. – Peter Oct 10 '18 at 12:15
  • I would suggest a bit more modern IDE – 0___________ Oct 10 '18 at 12:16
  • As an aside, avoid `sizeof(TYPE)`. `sizeof expression` is better for maintainability and error-avoidance. – Deduplicator Oct 10 '18 at 12:16
  • @Peter I see. If you lead me to use a good C compiler, i would be glad. – ibrahimG. Oct 10 '18 at 12:17

4 Answers4

10

This looks like C code, but you're compiling with a C++ compiler. As such, it complains on the line you mentioned because malloc returns a void * but you're assigning the result to a triangle *.

In C++ an explicit cast is required for this. In C, a void * may be implicitly converted to or from any object pointer type.

Since this appears to be C code and not C++ code, you should compile with a C compiler.

dbush
  • 205,898
  • 23
  • 218
  • 273
2

You compile this program as C++ program and this implicit conversion is not allowed in C++.

As I know dev C++ uses MinGW and you may use -xc option to compile program as C program or Settings -> language standard -> and choose the language standard needed

0___________
  • 60,014
  • 4
  • 34
  • 74
2

The code looks like C code but you are compiling it with C++ compiler.

  • Make sure that the file has proper extension for C++(not .c extension).

  • malloc() returns a (void *) pointer by default, so you have to explicitly cast the (void *) to (triangle *) in your code.

  • But if you are writing C++ code then I would recommend not to use malloc and free, instead try to use "new" operator in C++ since while instantiating objects it will call the constructors as well(unlike in malloc).

So to avoid complications go with new and delete in C++.


The code in C should look like (file a.c)
Compile using: gcc a.c -o a.o
Run using : ./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;
}


The same code in C++ would look like (file a.cpp)
Compile using: g++ a.cpp -o a.o
Run using : ./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;
}
shirish
  • 668
  • 4
  • 9
0
triangle *tr = (triangle*)malloc(n * sizeof(triangle));

Change the line as shown above. malloc returns generic pointer, so you need to explicitly typecast it to your desired pointer.

Refer this

Community
  • 1
  • 1
  • Unnecessarily overriding the type-system is an abomination, and there's no need to cast a `void*` to a different data-pointer-type ever. Also, avoid `sizeof(TYPE)`. – Deduplicator Oct 10 '18 at 12:20
  • He should compile using the compiler for language the program was written. – 0___________ Oct 10 '18 at 12:20