ali*_*n01 1 c variables overwrite mpi name-conflict
在我的大学练习中,我遇到了变量的奇怪行为.
/* Main parameters */
double sizeX, sizeY; /* Size of the global domain */
int nPartX, nPartY; /* Particle number in x, y direction */
int nPart; /* Total number of particles */
int nCellX, nCellY; /* (Global) number of cells in x, y direction */
int steps; /* Number of timesteps */
double dt; /* Stepsize for timesteps */
int logs; /* Whether or not we want to keep logfiles */
void ReadInput(const char *fname)
{
FILE *fp;
char c;
Debug("ReadInput", 0);
if(rank == 0)
{
fp = fopen(fname, "r");
if(!fp) Debug("Cannot open input file", 1);
if(fscanf(fp, "sizeX: %lf\n", &sizeX) != 1) Debug("sizeX?", 1);
if(fscanf(fp, "sizeY: %lf\n", &sizeY) != 1) Debug("sizeY?", 1);
if(fscanf(fp, "nPartX:%i\n", &nPartX) != 1) Debug("nPartX?", 1);
if(fscanf(fp, "nPartY:%i\n", &nPartY) != 1) Debug("nPartY?", 1);
if(fscanf(fp, "nCellX:%i\n", &nCellX) != 1) Debug("nCellX?", 1); //read value is 10
if(fscanf(fp, "nCellY:%i\n", &nCellY) != 1) Debug("nCellY?", 1);
if(fscanf(fp, "steps: %li\n", &steps) != 1) Debug("steps?", 1);
//here the nCellX variable value 10 is changed somehow to 0
if(fscanf(fp, "dt: %lf\n", &dt) != 1) Debug("dt?", 1);
if(fscanf(fp, "logs: %c\n", &c) != 1) Debug("logs?", 1);
logs = (c == 'y');
fclose(fp);
}
printf("(%i) reporting in...\n", rank);
MPI_Bcast(&sizeX, 1, MPI_DOUBLE, 0, grid_comm);
MPI_Bcast(&sizeY, 1, MPI_DOUBLE, 0, grid_comm);
MPI_Bcast(&nPartX,1, MPI_INT, 0, grid_comm);
MPI_Bcast(&nPartY,1, MPI_INT, 0, grid_comm);
MPI_Bcast(&nCellX,1, MPI_INT, 0, grid_comm);
MPI_Bcast(&nCellY,1, MPI_INT, 0, grid_comm);
MPI_Bcast(&steps, 1, MPI_INT, 0, grid_comm);
MPI_Bcast(&dt, 1, MPI_DOUBLE, 0, grid_comm);
MPI_Bcast(&logs, 1, MPI_INT, 0, grid_comm);
nPart = nPartX * nPartY;
dt2 = dt * dt;
}
Run Code Online (Sandbox Code Playgroud)
老师和我得出结论,如果我们将变量名称从"nCellX"更改为"nCellX_2",问题就会消失,代码会按预期工作.另一个有趣的事情是,只有这个单一的全局变量有这个问题,其他变量才能正常工作.我想知道是否有人遇到过这种类型的问题.任何指南/解释将不胜感激.
如果这个问题不够清楚,请告诉我,如果需要完整代码,我也可以提供.通常,代码是粒子在单元格中的并行算法.
以下代码行可能会导致问题:
if(fscanf(fp, "steps: %li\n", &steps) != 1) Debug("steps?", 1);
Run Code Online (Sandbox Code Playgroud)
它%li
表示一个长整数,可能是64位,steps
而是a int
,可能是32位.格式说明符应该%i
代替%li
.
是否存在实际问题取决于环境(例如,如果构建64位应用程序,则很可能是一个问题).如果存在64位与32位不匹配,则fscanf
调用将覆盖内存并可能销毁steps
内存布局中的任何变量(可能是nCellX
).请注意,使用-Wall
选项应该警告您这种情况.为什么将nCellX的名称更改为不同的名称应掩盖问题尚不清楚,但似乎更改名称可能会导致内存中变量布局的更改; 我怀疑C标准是不允许的(虽然我没看过).
归档时间: |
|
查看次数: |
976 次 |
最近记录: |