2

私は C でコーディングを始めたばかりで、割り当てに多くの問題を抱えています。malloc と free を使用して、構造体を使用したレコード データベースを作成するとします。構造は私のデータベースとして機能します。レコードを追加および削除できる必要があります。また、構造体に配列を使用することはできませんが、コード内の他の場所で配列を使用できます。先生はコードをレイアウトする方法を教えてくれましたが、入力を保存してレコードに追加する方法がわかりません。何か助けて??

トラブルシューティングのために多くのコードをコメントアウトしています。main の下部にある 2 つの printf ステートメントもトラブルシューティング用です。名を印刷するようにできますが、姓を追加するとすぐにセグフォルトが発生します。私はこれが起こるためにメモリを割り当てていないと信じていますが、まだこのことを完全には理解していません..助けてください! ありがとう!!!!

4

6 に答える 6

1

問題は、タイプ「構造体レコード」の初期化の「ライブラリ」変数、または実際にはそれがないことにあります。

struct record library; //this will hold info for user input

fName および lName メンバーは、char への初期化されていないポインターです。バッファにメモリを割り当て、それらのポインタを初期化してそれらのバッファを指すようにします。初期化されていないポインタは、単に「ある」メモリ位置を指しています。その場所にデータを入れると、何でも起こりえます! または、次のようなポインターの代わりに固定サイズのバッファーを提供します。

struct record {
    char fName[100];
    char lName[100];
};

それが最初のステップとして機能するはずです。次に、割り当てが示すように malloc/free を使用します。構造体レコードを元の形式に戻し、malloc を使用してバッファ用のメモリを予約してから、それらを関数に渡すか、別の方法で使用します。そのようです

#define BUFSIZE (100)
library.fName = malloc(BUFSIZE);
library.lName = malloc(BUFSIZE);

メモリ予約後はそれらを使用できますが、それらのバッファに BUFSIZE を超える文字数を渡さないでください。

バッファの使用が完了したら、割り当てられたメモリを解放します。

free(library.fName);
free(library.lName);

バッファを解放した後は、それらを使用できなくなります。gets() も使用しないでください。最大バッファー サイズが gets() のパラメーターとして渡されないため、バッファー オーバーフローに対する保護は提供されません。これは推奨されておらず、今後の標準 C1X から安全でないものとして削除される予定です。

于 2013-10-03T19:51:20.637 に答える
0

あなたが抱えている問題は、実際には入力を保存するためのメモリを割り当てていないことです。あなたの構造体から始めましょう:

   struct record{
     char * fName;
     char * lName;
   };         

メモリ内では、この構造体は 2 つの char ポインターにすぎません。構造体自体の長さは 8 バイトです。ポインターは何にも初期化されていないため、ランダムな値を持ちます。それらをポインタとして使用すると、メモリ内のランダムな場所を指します。

姓名を実際に構造体に格納したい場合は、次のように構造体を作成できます。

   static const int MaxNameLength = 255;
   struct record{
     char fName[MaxNameLength + 1];
     char lName[MaxNameLength + 1];
   };         

または、記述した方法で構造体を使用することもできますが、バッファにメモリを割り当て、ポインタを更新します。あなたがそれをした場合、これを行う必要があります:

static const int MaxNameLength = 255;
struct Record library;
library.fName = (char *)malloc(MaxNameLength + 1);
library.lName = (char *)malloc(MaxNameLength + 1);

どちらの方法も有効ですが、最初の方法の利点は、自分でメモリをクリーンアップする必要がないことです。構造体がスコープ外になると、すべてのメモリが解放されます。メモリを自分で malloc する場合は、メモリを解放する必要もあります。

于 2013-10-03T19:38:37.973 に答える
0

fName と lName はポインターです。一般に、各ポインターにメモリを割り当て、各ポインターのメモリを解放する必要があります。割り当てられていないメモリ セグメンテーション フォールトが発生するポインターで読み取りまたは書き込みを行うと、name[20] のような配列を作成し、gets 関数を使用できます。lName と fName に malloc(strlen(name)) のようにメモリを割り当てます。後で最後に無料で。問題が発生する可能性があるため、main 関数で malloc と free を実行してみてください (値渡しと参照渡しの問題については後で学習します)。

于 2013-10-03T20:16:27.120 に答える
0

どの構造体メンバーにもメモリが割り当てられていません。簡単にするために、最初に次のように定義します。

char fName[10]; 
char lName[10]; 
etc, 

これに慣れたら、メモリ割り当てを試してください。(IOW、一度に 1 つのコンセプト)

于 2013-10-03T19:28:08.067 に答える
0
 struct record{
   char * fName;
   char * lName;
   //char * sAddress;
   //char * city;
   //char * state;
   //int * zip;
   };   

あなたの構造では、 char * fname を使用しています

しかし、あなたの入力方法は正しくありませんでした。そのためにmallocを実行する必要があります

しかし、Cの初心者にとっては

fname と lname を char 配列として保持する

struct record{
       char fName[100];
       char lName[100];
       //char * sAddress;
       //char * city;
       //char * state;
       //int * zip;
       };  

上記のコードが正常に動作するようになりました..

于 2013-10-03T19:41:33.087 に答える