1

ダブル ポインターを作成し、アドレスを送信してメモリを割り当てますが、これにはトリプル ポインターが必要です。また、シングル ポインター (ゴールとアシスト) を作成し、そのアドレスを送信してメモリを割り当てますが、これにはダブル ポインターが必要です。問題はメモリの割り当てにあると思いますが、わかりません。readLinesFromFile 関数を実行するたびに、セグ フォールトが発生し続けます。allocateMemory 関数を単独で実行しようとすると、セグメンテーション違反は発生しません。問題は readLinesFromFile 関数にもある可能性があります

int main (int argc, char **argv)
{
    int numPlayers = 0;
    if (argc != 3)
    {
        printf("Missing text file");
        return 0;
    }
    char **playerNames;
    int *goals, *assists;


        FILE *filePtr = fopen(argv[1],"r");

         if(filePtr == NULL)
         {
             printf("\nFile is empty");
             return 0;
         }
  numPlayers = countLinesInFile(filePtr);

  allocateMemory(&goals,&assists,&playerNames,numPlayers);

  readLinesFromFile(filePtr,goals,assists,playerNames,numPlayers);


}


void allocateMemory(int **goals, int **assists, char *** names, int size)
{

    int i = 0;

    *goals = malloc(MAX_NAME * sizeof(int));

    *assists = malloc(MAX_NAME * sizeof(int));

    *names = malloc(MAX_NAME * sizeof(char*));

    for (i = 0; i < size; i++)
    {
        (names[i]) = malloc(MAX_NAME * sizeof(char*));
    }
}
void readLinesFromFile(FILE *fptr, int *goals, int *assists, char **names, int numLines)
{

    int i = 0, j = 0, x = 0;

    char players[MAX_LINE];

    char *tokenPtr;

   fptr = fopen(INPUT,"r");

   for(i = 0; i < numLines; i++)
   {
       fgets(players,MAX_LINE, fptr);

       tokenPtr = strtok(players," ");
       strcpy((*(names+i)), tokenPtr);

       while (tokenPtr != NULL)
       {
           tokenPtr = strtok(NULL," ");
           if (x = 0)
           {
               goals[i] = atoi(tokenPtr);
               x = 1;
           }
           else
           {
               assists[i] = atoi(tokenPtr);
               x = 0;
           }
       }
   }
}
4

1 に答える 1

0

MAX_NAMEがプレーヤーの名前の最大長であると仮定すると、これは機能するはずです。

void AllocateMemory(char *** pppNames, int ** ppGoals, int ** ppAssists, size_t sizePlayersMax)
{
  *pppNames = malloc(sizePlayersMax * sizeof **pppNames);
  *ppGoals  = malloc(sizePlayersMax * sizeof **ppGoals);9
  *ppAssists = malloc(sizePlayersMax * sizeof **ppAssists);

  {
    size_t sizePlayersCount = 0;0
    for (; sizePlayersCount < sizePlayersMax; ++sizePlayersCount)
    {
      (*pppNames)[sizePlayersCount] = calloc(MAX_NAME + 1, sizeof *((*pppNames)[sizePlayersCount]));
    }
  }
}

非常に長いプレーヤー名の場合にアプリがメモリを上書きしないようにするには、次の行を変更することをお勧めします。

strcpy((*(names+i)), tokenPtr);

なる:

if (tokenPtr) 
  strncpy((*(names+i)), tokenPtr, MAX_NAME);

これにより、保存されているプレイヤー名が最大MAX_NAME文字数に切り詰められます。後者はサイズAllocateMemory()使用マイナス1です。この 1 つのスペア文字は、0/NULが文字配列を終了して「文字列」として使用できるようにするために必要です。

最後に、これも危険です:

while (tokenPtr != NULL)
{
  tokenPtr = strtok(NULL," ");

  if (x = 0)
  {

次のようにするとよいでしょう:

while (NULL != (tokenPtr = strtok(NULL," ")))
{
  if (x = 0)
  {
于 2013-02-23T10:29:36.517 に答える