I'm using malloc with structures but get some errors like
Error 1 error C2440: 'initializing' : cannot convert from 'void *' to 'my_vector *' c:\\lab3\\lab3\\linalg.cpp 19 lab3
I'm making MPI application and set all needed settings. I'm tried some solution but it doesn't helps.
linalg.cpp
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <mpi.h>
#include "linalg.h"
void fatal_error(const char *message, int errorcode)
{
printf("fatal error: code %d, %s\n", errorcode, message);
fflush(stdout);
MPI_Abort(MPI_COMM_WORLD, errorcode);
}
struct my_vector *vector_alloc(int size, double initial)
{
struct my_vector *result = malloc(sizeof(struct my_vector) +
(size-1) * sizeof(double));
result->size = size;
for(int i = 0; i < size; i++)
{
result->data[i] = initial;
}
return result;
}
void vector_print(FILE *f, struct my_vector *vec)
{
for(int i = 0; i < vec->size; i++)
{
fprintf(f, "%.15lf ", vec->data[i]);
}
fprintf(f, "\n");
}
struct my_matrix *matrix_alloc(int rows, int cols, double initial)
{
struct my_matrix *result = malloc(sizeof(struct my_matrix) +
(rows * cols - 1) * sizeof(double));
result->rows = rows;
result->cols = cols;
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
result->data[i * cols + j] = initial;
}
}
return result;
}
void matrix_print(FILE *f, struct my_matrix *mat)
{
for(int i = 0; i < mat->rows; i++)
{
for(int j = 0; j < mat->cols; j++)
{
fprintf(f, "%lf ", mat->data[i * mat->cols + j]);
}
fprintf(f, "\n");
}
}
struct my_matrix *read_matrix(const char *filename)
{
FILE *mat_file = fopen(filename, "r");
if(mat_file == NULL)
{
fatal_error("can't open matrix file", 1);
}
int rows;
int cols;
fscanf(mat_file, "%d %d", &rows, &cols);
struct my_matrix *result = matrix_alloc(rows, cols, 0.0);
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
fscanf(mat_file, "%lf", &result->data[i * cols + j]);
}
}
fclose(mat_file);
return result;
}
struct my_vector *read_vector(const char *filename)
{
FILE *vec_file = fopen(filename, "r");
if(vec_file == NULL)
{
fatal_error("can't open vector file", 1);
}
int size;
fscanf(vec_file, "%d", &size);
struct my_vector *result = vector_alloc(size, 0.0);
for(int i = 0; i < size; i++)
{
fscanf(vec_file, "%lf", &result->data[i]);
}
fclose(vec_file);
return result;
}
void write_vector(const char *filename, struct my_vector *vec)
{
FILE *vec_file = fopen(filename, "w");
if(vec_file == NULL)
{
fatal_error("can't open vector file", 1);
}
vector_print(vec_file, vec);
fclose(vec_file);
}
I have problem at this place
struct my_vector *result = malloc(sizeof(struct my_vector) +
(size-1) * sizeof(double));
Your code is probably being compiled with a C++ compiler. The fact that your code is named ".cpp" is also quite telling, that's the typical extension for C++.
In C++, you cannot convert from void *
to other pointers without a cast:
my_vector *result = (my_vector *) malloc(...);
but you can drop the struct
since that's implicit in C++. Also, in C++ you're supposed to use new
:
my_vector *result = new my_vector[...];
which does away with the need to cast.
As you can see, C and C++ are not the same . You need a C compiler, if you want to program in C.
malloc
returns void *
. In C++ you must cast it to the appropriate pointer type:
struct my_vector *result = (struct my_vector *)malloc(...)
struct my_matrix *result = malloc(sizeof(struct my_matrix) +
(rows * cols - 1) * sizeof(double));
In C++ there is no implicit conversion from void *
to other pointer types, so you will have to cast the value returned by malloc
. Note that you probably should use new[]
instead.
This line suggests that you intend to write beyond the bounds of an array within struct my_matrix
. That would cause undefined behaviour. It is possible to design your MPI structures to not use this so-called "struct hack". For some examples that you can model your design from, take a look at the headers of an open-source MPI library.
NB. I see you tagged this post as "C" and "C++". Please decide which language you are using. Trying to write code that is source-compatible between two different languages is a terrible idea. Headers, yes, function implementations, no.
The code looks like a legal C, so it will compile with a C compiler. However, it won't in C++. C++ has a stronger type checking rule. Casting the result of malloc (which is void*
) to the appropriate pointer type should work, however.
You are compiling your C code as C++ code. In C++, you need a cast for your specific situation (see the other answers for examples), whereas you don't need it in C.
Rename your files so they have *.c
extensions and it should work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.