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()使用减号的大小10/需要这个备用字符NUL来终止字符数组,因此它可以用作“字符串”。

最后这也是危险的:

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

  if (x = 0)
  {

最好这样做:

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