0

C を使用しています。ヘッダー ファイルを指すメイン ファイルがあります。前者を「メイン」、後者の実装を「サプリメント」と呼ぶことにします。Main ファイルが実行されると、Supplement から関数が呼び出されます。

この関数は、グローバル変数を malloc して編集します (Supplement ファイル内)。次に、Supplement ファイルから別の関数を再度呼び出します。

これを行うたびにセグメンテーション違反が発生するため、問題はここにあります。gcc を使用して、Supplement への 2 回目の関数呼び出し中に、編集したグローバル変数が「消える」ように見えることを確認できました (print により、それが 0x0 アドレスにあり、アクセスできないことが示されます)。

私は C の初心者で、グローバル変数が悪いことは知っていますが、これは割り当てであり、メイン ファイルを編集できないため、追加ファイルでグローバル変数を使用して変数を「記憶」させることしかできません。

カットコード:

Main:
  // call load
 // check

Supplement:

    typedef struct node
{
    bool is_word;
    struct node* children[27];
}node;

//Root Node
static node* root = NULL;

bool check(const char* word)
{
  //edits word and puts it into input[i](as int)
  for(int i=0;i<x;i++)
    { 
       //uses root[input[i]] -this is the problem. Apparently root is 0x0.
    }
}

bool load(const char* dictionary)
{
     //mallocs and edits root. Note that it is quite a handful. Do note that in the context of this function, gdb returns seems to know root. It's just on the check function call that it mysteriously disappears.

//current = root

node* cur = root;
root = malloc(sizeof(node));

//Check if opened
if(dict==NULL)
{
    return false;
}else
{
    int ch = getc(dict);
    while(ch!=EOF)
    {
        //if character is newline
        if(ch==10)
        {
            cur->is_word = true;
            cur = root;
            dSize++;
        }else{
            int value = (ch==APOST)? 26 : ch-ASCII;
            //if there are no nodes yet
            if(cur->children[value]==NULL)
            {
                //make a new node
                node* next = malloc(sizeof(node));
                //point children to node
                cur->children[value]= next;  
                //current becomes new node
                cur= next;
            }else{
            //else, use node
                cur=cur->children[value];
            }
        }
        ch = getc(dict);
    };
    return true;
}

}

実際、ルート変数を設定しています。私のコードがそのようなコメントを引き出す理由がわかりません。また、ルートをgdbに出力することでこれを確認しています。唯一の問題は、ロードが完了した後、チェックを実行していて、ルートがなくなっていることです。前もって感謝します!

4

2 に答える 2

1

コードが表示されないため、特定のケースでエラーが発生する理由がわかりません。ただし、これを行う適切な方法は次のとおりです。

main.c

#include "supp.h"
#include <stdio.h>

int main()
{
  set_x (5);
  printf("%d", get_x());
  return 0;
}

supp.h

#ifndef SUPP_H
#define SUPP_H

void set_x (int n);
int  get_x (void);

#endif /* SUPP_H */

supp.c

#include "supp.h"

static int x;

void set_x (int n)
{
  x = n;
}

int get_x (void)
{
  return x;
}

このコードは、cファイル内で「ファイルスコープ」静的変数を使用します。他のファイルからxに直接アクセスすることはできません。これはプライベートカプセル化と呼ばれ、常に優れたプログラミング手法であり、オブジェクト指向プログラム設計と呼ばれる概念の一部です。

于 2013-01-31T10:28:35.077 に答える
0

グローバル変数を使用する理由はありません。main() で変数を宣言し、その変数への参照をそれを使用する関数に与えることができます。

bool load(node** root, const char* dictionary);
bool check(node* root, const char* word);

int main()
{
  node* root = NULL;

  load(&root, dictionary);

  ...
  if ( check(node,word) ) 
  {
  ...
  }
}
于 2013-01-31T11:34:52.340 に答える