0

List と呼ばれる 2 つの 2D char 配列を基本的に含む C 構造体があります。1 つは追加されたアイテム用で、もう 1 つは挿入されたアイテム用です。次に、add_to_array と呼ばれるこれらの配列に C 文字列を追加する外部関数を使用します。

私が抱えている問題は、 add_to_array を問題なく実行した後、もう一度呼び出すと、セグメンテーション違反が発生することです。テスト コードを使用して、何らかの理由で、リスト内の 2D 配列が add_to_array を呼び出した後も NULL のままであることを発見しました。add_to_array の結果を確認したところ、毎回 1 (成功) が返されます。

ターゲット システム/OS は Ubuntu linux です。

typedef struct
{
  char** appended;
  char** inserted;
  size_t app_alloc;
  size_t app_elem;
  size_t ins_alloc;
  size_t ins_elem;
}
List;

void init_list(List* list)
{
  list->app_alloc = 0;
  list->ins_alloc = 0;
  list->app_elem = 0;
  list->ins_elem = 0;
  list->appended = NULL;
  list->inserted = NULL;
}

void free_list(List* list)
{
  size_t i = 0;

  for (; i < list->ins_elem; ++i)
  {
    free(list->inserted[i]);
  }
  free(list->inserted);

  i = 0;

  for (; i < list->app_elem; ++i)
  {
    free(list->appended[i]);
  }
  free(list->appended);
}


int add_to_array(const char* in, char** array, size_t* alloc, size_t* elem)
{
  if (*alloc == *elem)
  {
    if (*alloc == 0) *alloc = list_buff;
    else             *alloc = (*alloc) * 2;

    char** _tmp = (char**) realloc(array, (*alloc) * sizeof(char*));

    if (!_tmp) return 0;
    else       array = _tmp;
  }

  array[(*elem)] = (char*) malloc(strlen(in) + 1);

  strcpy(array[(*elem)], in);

  (*elem)++;

  return 1;
}

int append_list(const char* in, List* out)
{
  return add_to_array(in, out->appended, &out->app_alloc, &out->app_elem);
}

int insert_list(const char* in, List* out)
{
  return add_to_array(in, out->inserted, &out->ins_alloc, &out->ins_elem);
}

int main()
{
  List test;

  init_list(&test);

  append_list("test", &test);

  if (!test.appended)
  {
    printf("*%s*", "why is test.appended still NULL?");
  }

  //append_list("wwww", &test);
  //insert_list("ffff", &test);

  //printf("%s\n", get_element(0, &test));
  //printf("%s\n", get_element(1, &test));
  //printf("%s\n", get_element(2, &test));

  //free_list(&test);


  return 0;
}

出力: なぜ test.appended はまだ NULL なのですか?

デビッドのアドバイスのおかげで、コードが機能するようになりました。変更点は次のとおりです。

int add_to_array(const char* in, char*** array, size_t* alloc, size_t* elem)
{
  if (*alloc == *elem)
  {
    if (*alloc == 0) *alloc = list_buff;
    else             *alloc = (*alloc) * 2;

    char** _tmp = (char**) realloc((*array), (*alloc) * sizeof(char*));

    if (!_tmp) return 0;
    else       (*array) = _tmp;
  }

  (*array)[(*elem)] = (char*) malloc(strlen(in) + 1);

  strcpy((*array)[(*elem)], in);

  (*elem)++;

  return 1;
}

int append_list(const char* in, List* out)
{
  return add_to_array(in, &out->appended, &out->app_alloc, &out->app_elem);
}

int insert_list(const char* in, List* out)
{
  return add_to_array(in, &out->inserted, &out->ins_alloc, &out->ins_elem);
}
4

1 に答える 1

1

Cは値渡し言語なので:-)

あなたが電話するとき、あなたはそれを期待しているようです:

add_to_array(in, out->appended, &out->app_alloc, &out->app_elem);

そして、する

int add_to_array(const char* in, char** array, size_t* alloc, size_t* elem)
{
....
array = _tmp;
....

への変更arrayも変更されout->appendedます。

そのように動作させたい場合は、へのポインターを渡して、次のようにする必要がありout->appendedます add_to_array

int add_to_array(const char* in, char*** array, size_t* alloc, size_t* elem)
于 2012-06-06T03:15:35.707 に答える