2

我编写了一个简单的 C 代码,它使用引擎根据用户输入运行两种不同的算法。它使用指向算法方法和对象的函数指针。在某处我无法追踪到一个令人讨厌的内存错误,所以也许我以错误的方式分配内存。出了什么问题?

下面是(相关部分)代码的最小工作示例。

主程序

#include "engine.h"

int main()
{
  char *id = "one";

  Engine_t eng;

  Engine_init(&eng);
  Engine_select_algorithm(eng, id);
  Engine_run(eng);
}

引擎.h

typedef struct _Engine *Engine_t;

引擎.c

#include "engine.h"
#include "algorithm_one.h"
#include "algorithm_two.h"

typedef struct _Engine
{ 
  void *p_algorithm;

  void (*init)(Engine_t);
  void (*run)(Engine_t);

} Engine;

void Engine_init(Engine_t *eng)
{
  *eng = malloc(sizeof(Engine));

  (*eng)->p_algorithm = NULL;
}

void Engine_select_algorithm(Engine_t eng, char *id)
{
  if ( strcmp(id, "one") == 0 )
    {
      eng->init = Algorithm_one_init;
      eng->run  = Algorithm_one_run;
    }
  else if ( strcmp(id, "two") == 0 )
    {
      eng->init = Algorithm_two_init;
      eng->run  = Algorithm_two_run;
    }
  else
    {
      printf("Unknown engine %s.\n", id); exit(0);
    }

  eng->init(eng);
}

void Engine_run(Engine_t eng)
{
  eng->run(eng);
}

void Engine_set_algorithm(Engine_t eng, void *p)
{
  eng->p_algorithm = p;
}

void Engine_get_algorithm(Engine_t eng, void *p)
{
  p = eng->p_algorithm;
}

算法_one.h

typedef struct _A_one *A_one_t;

algorithm_one.c

#include "engine.h"
#include "algorithm_one.h"

typedef struct _A_one
{ 
  float value;
} A_one;

void Algorithm_one_init(Engine_t eng)
{
  A_one_t aone;
  aone = malloc(sizeof(A_one));
  aone->value = 13.0;

  //int var = 10;

  Engine_set_algorithm(eng, &aone);
}

void Algorithm_one_run(Engine_t eng)
{  
  A_one_t aone;
  Engine_get_algorithm(eng, &aone);

  printf("I am running algorithm one with value %f.\n", aone->value);
  // The code for algorithm one goes here.
}

algorithm_two.halgorithm_two.c的代码与算法一文件相同。

一定存在内存错误,因为代码按给定的方式运行,但如果我取消注释

//int var = 10;

algoritm_one.c中的行代码因分段错误而崩溃。

4

1 回答 1

2

你把错误的东西传递给Engine_set_algorithm. 您传递的是局部变量的地址,而不是算法的地址。你需要写:

Engine_set_algorithm(eng, aone);

而且也是Engine_get_algorithm错的。您通过值传递一个指针并修改该指针。所以调用者看不到那个修改。你需要它是:

void Engine_get_algorithm(Engine_t eng, void **p)
{
  *p = eng->p_algorithm;
}

我认为如果您定义一个类型来表示算法,您的代码会更容易。该类型只是 a void*,但它会使代码更易于阅读。更重要的是,我会Engine_get_algorithm返回算法。

algorithm Engine_get_algorithm(Engine_t eng)
{
    return eng->p_algorithm;
}

void Engine_set_algorithm(Engine_t eng, algorithm alg)
{
    eng->p_algorithm = alg;
}
于 2013-01-22T11:14:56.853 回答