简体   繁体   English

将malloc与结构一起使用

[英]Use malloc with structure

I'm using malloc with structures but get some errors like 我正在将malloc与结构一起使用,但会遇到一些错误,例如

Error 1 error C2440: 'initializing' : cannot convert from 'void *' to 'my_vector *' c:\\lab3\\lab3\\linalg.cpp 19 lab3 错误1错误C2440:'正在初始化':无法从'void *'转换为'my_vector *'c:\\ lab3 \\ lab3 \\ linalg.cpp 19 lab3

I'm making MPI application and set all needed settings. 我正在制作MPI应用程序并设置所有需要的设置。 I'm tried some solution but it doesn't helps. 我尝试了一些解决方案,但没有帮助。

linalg.cpp 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. 您的代码可能正在使用C ++编译器进行编译。 The fact that your code is named ".cpp" is also quite telling, that's the typical extension for C++. 您的代码名为“ .cpp”的事实也很清楚,这是C ++的典型扩展。

In C++, you cannot convert from void * to other pointers without a cast: 在C ++中,如果没有强制转换,则无法从void *转换为其他指针:

my_vector *result = (my_vector *) malloc(...);

but you can drop the struct since that's implicit in C++. 但是您可以删除该struct因为该struct在C ++中是隐式的。 Also, in C++ you're supposed to use new : 另外,在C ++中,您应该使用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 . 如您所见,C和C ++ 并不相同 You need a C compiler, if you want to program in C. 如果要使用C进行编程,则需要C编译器。

malloc returns void * . malloc返回void * In C++ you must cast it to the appropriate pointer type: 在C ++中,必须将其强制转换为适当的指针类型:

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 . 在C ++中,没有从void *到其他指针类型的隐式转换,因此您必须转换malloc返回的值。 Note that you probably should use new[] instead. 请注意,您可能应该改用new[]

This line suggests that you intend to write beyond the bounds of an array within struct my_matrix . 这行代码建议您打算在struct my_matrix内的数组范围之外进行写入。 That would cause undefined behaviour. 这将导致不确定的行为。 It is possible to design your MPI structures to not use this so-called "struct hack". 可以将MPI结构设计为不使用这种所谓的“结构hack”。 For some examples that you can model your design from, take a look at the headers of an open-source MPI library. 对于可以用来对设计进行建模的一些示例,请看一下开源MPI库的标头。

NB. 注意 I see you tagged this post as "C" and "C++". 我看到您将此帖子标记为“ C”和“ 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. 该代码看起来像合法的C,因此可以使用C编译器进行编译。 However, it won't in C++. 但是,在C ++中不会。 C++ has a stronger type checking rule. C ++具有更强的类型检查规则。 Casting the result of malloc (which is void* ) to the appropriate pointer type should work, however. 但是,将malloc的结果( void* )强制转换为适当的指针类型应该可以。

You are compiling your C code as C++ code. 您正在将C代码编译为C ++代码。 In C++, you need a cast for your specific situation (see the other answers for examples), whereas you don't need it in C. 在C ++中,您需要针对特定​​情况进行强制转换(请参见其他答案以获取示例),而在C中则不需要。

Rename your files so they have *.c extensions and it should work. 重命名文件,使它们具有*.c扩展名,并且可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM