2

ユーザー入力に応じて 2 つの異なるアルゴリズムを実行するエンジンを使用する単純な C コードを作成しました。アルゴリズムのメソッドとオブジェクトへの関数ポインターを使用します。私が追跡できない厄介なメモリバグがどこかにあるので、間違った方法でメモリを割り当てている可能性があります。何がうまくいかないのですか?

以下は、コードの最小限の作業例 (の関連部分) です。

main.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;
}

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のコードは、アルゴリズム 1 ファイルと同じです。

コードは指定どおりに実行されるため、メモリのバグが関係しているに違いありませんが、コメントを外すと

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

アルゴリズムを表す型を定義すると、コードが簡単になると思います。その型は単なる になります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 に答える