我在递归函数中传递指针时遇到问题。
我的来源片段是:
#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的原始地址也不会改变。知道我有一些事情要定义为“指针指针”,但我如何处理将信息存储到我的结构中呢?
如果这样做,这有助于避免指针无效吗?
提前致谢...
答案 0 :(得分:0)
您的问题是您将Grid
参数传递给Read_File
函数按值(这是在C中传递参数的唯一方法),但随后分配给函数内部的Grid
变量和expect期望更改调用函数时使用的变量。
通过按值传递指针,您可以创建原始指针的副本,如您所知,修改副本不会修改原始指针。因此,当您在Grid
函数内分配Read_File
变量时,只修改函数中的副本,而不是调用函数时使用的变量。所以当Read_File
返回时,
您已经知道如何在c中模拟通过引用传递,因为指向int
参数的两个指针显示。您需要对Grid
参数执行相同操作,将指针传递给指针。