我正在用 C 語言構建一個程式來為我的博士研究運行一些模擬。基本上,程式使用一個函式來讀取具有一些重要值的輸入檔案,然后將這些值分配給main函式中的變數。其中一些值需要分配給陣列,x并且par在輸入檔案中也宣告了大小。為此,我需要在函式內部使用一些動態分配的記憶體,它指向指標的地址*x和*par.
我設法使用二維陣串列示法為這些指標分配值,但我不完全理解為什么需要這樣,因為函式指向的指標被初始化為NULL指標。
下面以最小功能代碼為例:
#include <stdio.h>
#include <stdlib.h>
void read_input(char *name, int *dim, int *npar, int *np, int *ndiv, double *t, double **par, double **x);
int main(void) {
int DIM;
int nP;
int nDiv;
int nPar;
// Assign values for program parameters, system parameters and initial conditions
char *input_filename = "input.txt";
double t;
double *par = NULL;
double *x = NULL;
read_input(input_filename, &DIM, &nPar, &nP, &nDiv, &t, &par, &x);
for (int i = 0; i < DIM; i ) {
printf("x[%i] = %.15lf\n", i, x[i]);
}
for (int i = 0; i < nPar; i ) {
printf("par[%i] = %lf\n", i, par[i]);
}
free(x);
free(par);
}
void read_input(char *name, int *dim, int *npar, int *np, int *ndiv, double *t, double **par, double **x) {
// Open input file
FILE *input = fopen(name, "r");
if (input == NULL) {
printf("Input File Not Found...\n");
return;
}
// Read and assign system constants
fscanf(input, "%i", dim);
fscanf(input, "%i", npar);
// Read and assign program parameters
fscanf(input, "%i %i", np, ndiv);
// Read and assign initial time
fscanf(input, "%lf", t);
// Allocate memory for x[dim] and par[npar] vectors
*x = malloc((*dim) * sizeof(double));
*par = malloc((*npar) * sizeof(double));
// Security check for pointers
if (*x == NULL || *par == NULL) {
free(*x);
free(*par);
printf("Memory allocation for *x or *par did not complete successfully");
return;
}
// assign IC to x[dim] vector
for (int i = 0; i < *dim; i ) {
fscanf(input, "%lf ", &x[i][i]);
}
for (int i = 0; i < *dim; i ) {
for (int j = 0; j < *dim; j ) {
printf("x[%i][%i] = %lf (address: %p)\n", i, j, x[i][j], &x[i][j]);
}
}
printf("==============================\n");
// Assign values to par[npar] vector
for (int i = 0; i < *npar; i ) {
fscanf(input, "%lf\n", &par[i][i]);
}
for (int i = 0; i < *npar; i ) {
for (int j = 0; j < *npar; j ) {
printf("par[%i][%i] = %lf (address: %p)\n", i, j, par[i][j], &par[i][j]);
}
}
printf("==============================\n");
// Close input file
fclose(input);
}
另外,我檢查了雙指標x[i][j]和par[i][j]指向的地址,它們對于 , 和 的每個組合都是相同[i][0], ..., [i][4]的i = 0 to 4:
x[0][0] = 0.707107 (address: 0000020B01C33FC0)
x[0][1] = 0.000000 (address: 0000020B01C33FC8)
x[1][0] = 0.707107 (address: 0000020B01C33FC0)
x[1][1] = 0.000000 (address: 0000020B01C33FC8)
==============================
par[0][0] = 1.000000 (address: 0000020B01C34580)
par[0][1] = 0.150000 (address: 0000020B01C34588)
par[0][2] = 0.025000 (address: 0000020B01C34590)
par[0][3] = -0.500000 (address: 0000020B01C34598)
par[0][4] = 1.000000 (address: 0000020B01C345A0)
par[1][0] = 1.000000 (address: 0000020B01C34580)
par[1][1] = 0.150000 (address: 0000020B01C34588)
par[1][2] = 0.025000 (address: 0000020B01C34590)
par[1][3] = -0.500000 (address: 0000020B01C34598)
par[1][4] = 1.000000 (address: 0000020B01C345A0)
par[2][0] = 1.000000 (address: 0000020B01C34580)
par[2][1] = 0.150000 (address: 0000020B01C34588)
par[2][2] = 0.025000 (address: 0000020B01C34590)
par[2][3] = -0.500000 (address: 0000020B01C34598)
par[2][4] = 1.000000 (address: 0000020B01C345A0)
par[3][0] = 1.000000 (address: 0000020B01C34580)
par[3][1] = 0.150000 (address: 0000020B01C34588)
par[3][2] = 0.025000 (address: 0000020B01C34590)
par[3][3] = -0.500000 (address: 0000020B01C34598)
par[3][4] = 1.000000 (address: 0000020B01C345A0)
par[4][0] = 1.000000 (address: 0000020B01C34580)
par[4][1] = 0.150000 (address: 0000020B01C34588)
par[4][2] = 0.025000 (address: 0000020B01C34590)
par[4][3] = -0.500000 (address: 0000020B01C34598)
par[4][4] = 1.000000 (address: 0000020B01C345A0)
==============================
x[0] = 0.707106781186547
x[1] = 0.000000000000000
par[0] = 1.000000
par[1] = 0.150000
par[2] = 0.025000
par[3] = -0.500000
par[4] = 1.000000
以下是 input.txt 檔案的格式:
2
5
1000 1000
0.0
0.707106781186547 0.0
1.0
0.15
0.025
-0.5
1.0
我在這里想念什么?
uj5u.com熱心網友回復:
在 2D 索引中的第一個索引為 non 的所有情況下,發布的代碼都具有未定義的行為0。例如:
fscanf(input, "%lf ", &x[i][i]);
x是函式中指標的int地址main。x[i]僅在iis時定義0,否則您正在從記憶體中的位置讀取超出main區域變數的位置,該位置具有未定義的行為,但可能會或可能不會導致問題。x[i][i]取消參考 valuex[i],這可能是一個無效的指標,因此很可能會導致崩潰。僅僅把這個地址當作&x[i][i]可能仍然被忽視,但是當fscanf()試圖在那里存盤一個int時,取消參考&x[i][i]將是一個問題。
令人驚訝的是,您的程式可以毫無問題地產生輸出。
此回圈的正確語法是
// assign IC to x[dim] vector
for (int i = 0; i < *dim; i ) {
fscanf(input, "%lf ", &(*x)[i]);
}
&(*x)[i]i是指向的陣列的第 - 個元素的地址*x。還有其他可能,但都不令人滿意:
&x[0][i](*x) i*x ix[0] ii *x&0[x][i]&i[*x]&i[0[x]]i 0[x]
是的,以上所有都是等價的......
更好的方法是定義具有正確型別的區域變數,read_input并在成功操作后將它們傳回給呼叫者。您還可以將所有這些變數分組到一個結構中并將指標傳遞給read_input:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int read_input(const char *name, int *pdim, int *pnpar,
int *pnp, int *pndiv, double *pt,
double **ppar, double **px)
{
// use regular variables
int dim, npar, np, ndiv;
double t;
double *par = NULL;
double *px = NULL;
// Open input file
FILE *input = fopen(name, "r");
if (input == NULL) {
printf("Cannot open file %s: %s\n", name, strerror(errno));
return -1;
}
// Read and assign system constants
if (fscanf(input, "%i %i", &dim, &npar) != 2)
goto invalid;
// Read and assign program parameters
if (fscanf(input, "%i %i", &np, &ndiv) != 2)
goto invalid;
// Read and assign initial time
if (fscanf(input, "%lf", &t) != 1)
goto invalid;
// Allocate memory for x[dim] and par[npar] vectors
x = calloc(dim, sizeof(double));
par = calloc(npar, sizeof(double));
// Security check for pointers
if (x == NULL || par == NULL) {
printf("Memory allocation for x or par did not complete successfully\n");
free(x);
free(par);
fclose(input);
return -1;
}
// assign IC to x[dim] vector
for (int i = 0; i < dim; i ) {
if (fscanf(input, "%lf", &x[i]) != 1)
goto invalid;
}
// Assign values to par[npar] vector
for (int i = 0; i < npar; i ) {
if (fscanf(input, "%lf", &par[i]) != 1)
goto invalid;
}
// Close input file
fclose(input);
// update valid data to the caller
*pdim = dim;
*pnpar = npar;
*pnp = np;
*pndiv = ndiv;
*pt = t;
*px = x;
*ppar = par;
return 0;
invalid:
printf("Invalid or missing input\n");
free(x);
free(par);
fclose(input);
return -1;
}
uj5u.com熱心網友回復:
我設法在一些文章中找到了為指標賦值的正確方法:
為此,應通過一維陣串列示法訪問指標,方法是將指標本身稱為:
scanf("%lf", &(*x)[i]);
代替
scanf("%lf", &x[i][i]);
然后,可以正確分配值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/486437.html
