Используйте malloc со структурой

0

Я использую malloc со структурами, но получаю некоторые ошибки, например

Ошибка 1 ошибка C2440: 'initializing': не может преобразовать из 'void *' в 'my_vector *' c:\lab3\lab3\linalg.cpp 19 lab3

Я делаю приложение MPI и устанавливаю все необходимые настройки. Я пробовал какое-то решение, но это не помогает.

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

У меня проблема в этом месте

struct my_vector *result = malloc(sizeof(struct my_vector) +
                                    (size-1) * sizeof(double));
  • 3
    Вы компилируете код C с помощью компилятора C ++?
  • 0
    @lethal-guitar Смертельная гитара, скорее всего, так. многие компиляторы C / C ++ (унифицированные) решают, какой язык использовать, основываясь на расширении. Таким образом, код скомпилирован как C ++
Показать ещё 3 комментария
Теги:
struct
mpi
malloc

5 ответов

6
Лучший ответ

Вероятно, ваш код компилируется с помощью компилятора C++. Тот факт, что ваш код называется ".cpp", также довольно говорит, что типичное расширение для C++.

В C++ вы не можете преобразовать из void * в другие указатели без приведения:

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

но вы можете отказаться от struct поскольку это подразумевается в C++. Кроме того, в C++ вы должны использовать new:

my_vector *result = new my_vector[...];

что избавляет от необходимости бросать.

Как вы можете видеть, C и C++ не совпадают. Вам нужен компилятор C, если вы хотите программировать на C.

4

malloc возвращает void *. В C++ вы должны применить его к соответствующему типу указателя:

struct my_vector *result = (struct my_vector *)malloc(...)
  • 0
    Все в порядке! Но могу ли я скомпилировать как C, но с поддержкой этого кода? Я думаю, что мне просто нужна поддержка стандарта C99. Я использую VS 2008.
  • 1
    @ АндрейСердюк Не с VS2008. Microsoft в значительной степени игнорировала C99 до самого недавнего времени. VS2013 добавил некоторую поддержку, но в более ранних версиях вы застряли с C89.
1
struct my_matrix *result = malloc(sizeof(struct my_matrix) + 
                                (rows * cols - 1) * sizeof(double));

В C++ нет никакого неявного преобразования из void * в другие типы указателей, поэтому вам нужно будет указать значение, возвращаемое malloc. Обратите внимание, что вы, вероятно, должны использовать new[].

Эта строка предполагает, что вы намереваетесь писать за пределами массива внутри struct my_matrix. Это приведет к неопределенному поведению. Можно создать свои структуры MPI, чтобы не использовать этот так называемый "хакер". Для некоторых примеров, с которых вы можете моделировать свой дизайн, взгляните на заголовки библиотеки MPI с открытым исходным кодом.

NB. Я вижу, что вы отметили этот пост как "C" и "C++". Выберите язык, который вы используете. Попытка написать код, совместимый с исходным кодом между двумя разными языками, - ужасная идея. Заголовки, да, реализация функций, нет.

0

Код выглядит как законный C, поэтому он будет компилироваться с компилятором C. Однако это не будет в C++. C++ имеет более сильное правило проверки типов. Однако результат работы malloc (который равен void*) на соответствующий тип указателя должен работать.

0

Вы компилируете свой код C как C++. В C++ вам нужна броска для вашей конкретной ситуации (см. Другие ответы для примеров), в то время как вам это не нужно в C.

Переименуйте свои файлы, чтобы они *.c и они должны работать.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню