在递归函数中将指针传递给结构

时间:2015-08-24 10:57:33

标签: c pointers recursion struct

我在递归函数中传递指针时遇到问题。

我的来源片段是:

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

#include "../Toolbox/Toolbox.h"
#include "../Toolbox/Reader.h"

#define NUM_OF_GRIDS       100
#define FILE_NAME_LEN      256
#define LINE_LEN           121

typedef struct{
  int ID;
  double Local_XYZ[3];
  double XYZ[3];
  int PosCoord;
  int Include;
  int Module;
  int ModNum;
} Type_Grid;


void Read_File(
char* ,// Name of the file to be read   
int*,//memory factor for Grids     
int*,//Number of Grids             
Type_Grid*//Struct Grid           
);



int main( void )  {

  char InputFileName   [FILE_NAME_LEN] = "test.bdf";

  int MemFacGrid          = 1; 

  int AnzGrid              = 0;

  Type_Grid* Grid;

  Grid = (Type_Grid*) calloc (NUM_OF_GRIDS, sizeof(Type_Grid) );

//###############################################################################################

  Read_File(
    InputFileName,     
    &MemFacGrid,          
    &AnzGrid,          
    Grid              
  );

  printf("reading completed\n\n"); 
  printf("AnzGrid %i @ %p\n",AnzGrid,Grid);                                                                           

  return EXIT_SUCCESS;
}
//
//###############################################################################################
//
// READ_FILE
//
//###############################################################################################
//

void Read_File(
char* InputFileName,                 
int* MemFacGrid,                        
int* AnzGrid,                        
Type_Grid* Grid                     
){

Type_Grid* tmpGrid;                     

char Line[LINE_LEN] = "\0";
char* Token=NULL;
FILE * File = NULL;

File = fopen(InputFileName,"r");

  if (!File){
    printf("%s not found!\n",InputFileName);
    return ;
  }else{
    printf("reading %s \n",InputFileName);
  }
  //if (!File) 

  while (fgets(Line,LINE_LEN,File)){

  if (Line[0] == '$') continue;

    if (strncmp(Line,"INCLUDE ",8) == 0){
      Token=strtok(Line,"'");
      Token=strtok(NULL,"'");

    printf("reading INCLUDE %s \n",Token);

      Read_File(
        Token,
        MemFacGrid,                        
        AnzGrid,                        
        Grid
      );

    }//if (strncmp(Line,"INCLUDE ",8) == 0) 

//
//###############################################################################################
//

    if ( strstr(Line,"GRID") ){
      Grid[(*AnzGrid)].ID          = atoi(Entry.Field[1]);
      Grid[(*AnzGrid)].PosCoord    = atoi(Entry.Field[2]);
      Grid[(*AnzGrid)].Local_XYZ[0]      = atof(Entry.Field[3]);
      Grid[(*AnzGrid)].Local_XYZ[1]      = atof(Entry.Field[4]);
      Grid[(*AnzGrid)].Local_XYZ[2]      = atof(Entry.Field[5]);

      if (Grid[(*AnzGrid)].PosCoord == 0){
        Grid[(*AnzGrid)].XYZ[0]      = atof(Entry.Field[3]);
        Grid[(*AnzGrid)].XYZ[1]      = atof(Entry.Field[4]);
        Grid[(*AnzGrid)].XYZ[2]      = atof(Entry.Field[5]);
      }//if (Grid[(*AnzGrid)].PosCoord == 0)

      (*AnzGrid)++;

      if ( (*AnzGrid) >= NUM_OF_GRIDS * (*MemFacGrid)) {

        printf("Number of GRIDs exceeded %i * %i @ %p ==> reallocate new memory\n", (*MemFacGrid), NUM_OF_GRIDS , Grid);

        (*MemFacGrid)++;

        printf("    new size for GRID is %i * %i\n", (*MemFacGrid), NUM_OF_GRIDS );

        tmpGrid = (Type_Grid*) realloc (tmpGrid, ( NUM_OF_GRIDS  * (*MemFacGrid) ) * sizeof(Type_Grid) );

        if (tmpGrid != NULL) {

          printf("    new adress for GRID is %p \n", tmpGrid);
          Grid=NULL;
          Grid=tmpGrid;

        }else{

          printf("#####     REALLOC error in line %i \n", __LINE__);

        }//if (tmpGrid != NULL)        

      }//if ( (*AnzGrid) >= NUM_OF_GRIDS * (*MemFacGrid)) 

    }//if ( mystrstr(Key,Keyword) )

  }//  while (fgets(Line,121,File)){


fclose(File);

return ;

}

抱歉,不要发送Toolbox.h和Reader.h(两者都有助于使用Inputfile的语法规则填充结构“Entry.Field [x]”),但可以看到主要逻辑。

输入文件的结构是,有一些信息存储在关键字GRID中,文件可以通过关键字INCLUDE构建,包括一个或多个其他文件。

每当发现INCLUDE时,我都会使用递归方法打开它。

我的问题是内存:每当GRID条目的数量超过NUM_OF_GRIDS时,我想通过因子* NUM_OF_GRIDS重新分配内存。

这可以正常工作,直到NUM_OF_GRIDS大到足以保留所有条目而不使用realloc。

如果NUM_OF_GRIDS太小,我会遇到一个coredump。

Stdout给出:

阅读test.bdf

阅读INCLUDE test1.bdf

阅读test1.bdf

GRID数超过1 * 100 @ 0xed6010 ==&gt;重新分配新内存

GRID的新尺寸为2 * 100

GRID的新地址是0xed80c0

GRID数超过2 * 100 @ 0xed6010 ==&gt;重新分配新内存

GRID的新尺寸为3 * 100

*检测到glibc * ./test:realloc():指针无效: 0x00007fff102aa890 ***

可以看出,即使重新分配完成,指向GRID的原始地址也不会改变。知道我有一些事情要定义为“指针指针”,但我如何处理将信息存储到我的结构中呢?

如果这样做,这有助于避免指针无效吗?

提前致谢...

1 个答案:

答案 0 :(得分:0)

您的问题是您将Grid参数传递给Read_File函数按值(这是在C中传递参数的唯一方法),但随后分配给函数内部的Grid变量和expect期望更改调用函数时使用的变量。

通过按值传递指针,您可以创建原始指针的副本,如您所知,修改副本不会修改原始指针。因此,当您在Grid函数内分配Read_File变量时,只修改函数中的副本,而不是调用函数时使用的变量。所以当Read_File返回时,

您已经知道如何在c中模拟通过引用传递,因为指向int参数的两个指针显示。您需要对Grid参数执行相同操作,将指针传递给指针。