0

割り当てられた各構造体を指すポインターの配列を使用して、いくつかの構造体に入力を割り当てようとしています。1つの構造を埋めて印刷しようとしましたが、エラーが発生し続け、理由がわかりません。何か案は?

助けてくれてありがとう。

/* Structure declaration */

struct personCatalog {
  char name[50];
  char address[50];
  char cityState[50];
  char zipCode[7];
} ;

//function to fill structures

void getPerson (struct personCatalog *ArrayOfPointers[]);

   int main(int argc, const char * argv[])
 {

struct personCatalog *pointerArray[51]; 

getPerson(pointerArray);

 }

void getPerson (struct personCatalog *ArrayOfPointers[]){

struct personCatalog *tempPointer;

char stringCollector[512];

int maxNumberOfPeople = 51;
int num = 0;

while ((gets(stringCollector) != NULL) && (num < maxNumberOfPeople)) {

    tempPointer = (struct personCatalog *) malloc(sizeof(struct personCatalog));
    strcpy(tempPointer->name, stringCollector);
    gets(tempPointer->address);
    gets(tempPointer->cityState);
    gets(tempPointer->zipCode);

    ArrayOfPointers[num] = tempPointer;

    num++;

    printf("%s", ArrayOfPointers[num]->name);
    printf("%s", ArrayOfPointers[num]->address);
    printf("%s", ArrayOfPointers[num]->cityState);
    printf("%s", ArrayOfPointers[num]->zipCode);

}

 ArrayOfPointers[num] = '\0';
}
4

2 に答える 2

1

少し修正して試してみてください。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Structure declaration */

struct personCatalog {
  char name[50];
  char address[50];
  char cityState[50];
  char zipCode[7];
} ;
const int maxNumberOfPeople = 3; // was 51;

//function to fill structures

void getPerson (struct personCatalog *ArrayOfPointers[]);

int main(int argc, const char * argv[]) {

  struct personCatalog *pointerArray[maxNumberOfPeople];

  getPerson(pointerArray);

}

void getPerson (struct personCatalog *ArrayOfPointers[]){
  struct personCatalog *tempPointer;
  char stringCollector[512];
  int num = 0;

  while ((num < maxNumberOfPeople) && (gets(stringCollector) != 0) ) {

    tempPointer = (struct personCatalog *) malloc(sizeof(struct personCatalog));
    strcpy(tempPointer->name, stringCollector);
    gets(tempPointer->address);
    gets(tempPointer->cityState);
    gets(tempPointer->zipCode);

    ArrayOfPointers[num] = tempPointer;


    printf("name      %s\n", ArrayOfPointers[num]->name);
    printf("address   %s\n", ArrayOfPointers[num]->address);
    printf("cityState %s\n", ArrayOfPointers[num]->cityState);
    printf("zipCode   %s\n", ArrayOfPointers[num]->zipCode);

    num++;
  }
  //ArrayOfPointers[num] = '\0'; this crashed at end of array
}
于 2012-11-24T21:26:08.480 に答える
1

興味深いことに、コードは必要なインクルードを追加して私のために機能します:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

ただし、これは妥当な入力にのみ当てはまります。コードには少し改善の余地がありますが、それについては後で詳しく説明します。

出力が表示されない理由はnum、データを構造体に割り当てた後、印刷する前にインデックスをインクリメントしているためです。つまり、ループでは、まだ割り当てられていないpoiter、つまりガベージを常に逆参照しています。nullポインタ(またはプロセスのメモリやセグメンテーション違反にないもの)を逆参照しようとするのは時間の問題です。

今欠陥のために:

  • malloc() 常に2つのものが付属しています:戻り値のチェックと対応するfree()!が欠落していますfree()が、データが不要になったときにそれを処理できるコードの他の部分があることを理解しています。ただし、NULLが返されない(つまり、メモリの割り当てに失敗した)かどうかはチェックしていません。これにより、プログラムがすぐにダウンします(nullポインターの逆参照によるSEGFAULT)。

  • gets()-この関数のマンページを読むことをお勧めします(Windowsを使用している場合は、インターネットで調べてください)-データの読み取りの制限を保証するものではないため、バッファを簡単にオーバーフローさせる可能性があります。fgets()代わりに使用してください。別の方法としてscanf()、幅指定子を使用することもできます%s

  • strcpy()-と同じですgets()。あなたが死んでいない限り、代わりに使用してくださいstrncpy()-それがあなたのデータを壊さないことを確認してください。さらに、あなたはにコピーchar stringCollector[512]char personCatalog.name[50]ています-それをしないでください。これは一貫性がなく、境界チェックを前者のサイズに基づいて行うと、問題が発生する可能性があります(遅かれ早かれ)。

最後になりましたが、1つずつエラーが発生しました(これを正しく行うのは難しい場合があります)。

struct personCatalog *pointerArray[51];
...
int maxNumberOfPeople = 51;
if (num < maxNumberOfPeople)) {
    ...
    num++;
    ...
}
ArrayOfPointers[num] = '\0'

最悪の場合、あなたは後ろに書くつもりですArrayOfPointersArrayOfPointers[51]具体的には)。

マクロを使用して、配列をNULLで終了するかどうかを決定します。

#define MAXPEOPLE 50
struct personCatalog *pointerArray[MAXPEOPLE+1]; /* +1 for the NULL terminator */
if (num < MAXPEOPLE)) ...
于 2012-11-24T22:20:34.820 に答える