[英]C - How to pass struct pointer array to a function by reference
我有這個結構:
typedef struct {
char name[31];
int played;
int won;
int lost;
int tie;
int points;
} Player;
這個 function 用文件中的數據填充結構數組:
int load(Player *players[], int max_players, int *player_count)
{
static const char filename[] = "players.txt";
FILE *file = fopen(filename, "r");
if (file != NULL)
{
char line[128];
players = malloc(max_players * sizeof *players);
while (1) /* read until end of file */
{
players[*player_count] = malloc(sizeof(Player));
if (*player_count < max_players && fgets(players[*player_count]->name, sizeof players[*player_count]->name, file) != NULL)
{
fscanf(file, "%d", &players[*player_count]->played); // read played
fscanf(file, "%d", &players[*player_count]->won); // read won
fscanf(file, "%d", &players[*player_count]->lost); // read lost
fscanf(file, "%d", &players[*player_count]->tie); // read tie
fscanf(file, "%d", &players[*player_count]->points); // read points
fgets(line, sizeof line, file); // read new line
// increase player count
*player_count += 1;
}
else
{
break;
}
}
fclose(file);
}
else
{
return 0;
}
return 1;
}
現在我在通過傳遞玩家作為參考來調用它時遇到問題,這樣玩家的更新數據就會反映在調用端。
下面是我的調用代碼,我認為它有問題:
Player *players[MAX_PLAYERS] = { NULL };
int playerCount = 0;
load(players, MAX_PLAYERS, &playerCount);
當我調試代碼時,玩家數組填入 function 但當它返回時,玩家的值仍然是 null。
任何幫助,將不勝感激。
您正在覆蓋本地變量players
。
從不需要的功能中刪除以下行。
players = malloc(max_players * sizeof *players);|
由於您已經在main
擁有了指針數組。
您不需要Player
類型的指針數組,而只需要Player
類型的數組
Player *players;
load(&players, MAX_PLAYERS, &playerCount);
並具有load
功能。
int load(Player **players, int max_players, int *player_count)
{
static const char filename[] = "players.txt";
FILE *file = fopen(filename, "r");
if (file != NULL)
{
char line[128];
(*players) = malloc(max_players * sizeof **players);
while (1) /* read until end of file */
{
if (*player_count < max_players && fgets((*players)[*player_count].name, sizeof (*players)[*player_count].name, file) != NULL)
{
fscanf(file, "%d", &(*players)[*player_count].played); // read played
fscanf(file, "%d", &(*players)[*player_count].won); // read won
fscanf(file, "%d", &(*players)[*player_count].lost); // read lost
fscanf(file, "%d", &(*players)[*player_count].tie); // read tie
fscanf(file, "%d", &(*players)[*player_count].points); // read points
fgets(line, sizeof line, file); // read new line
// increase player count
*player_count += 1;
}
else
{
break;
}
}
fclose(file);
}
else
{
return 0;
}
return 1;
}
C不支持通過引用傳遞變量。
我只是保持簡單。 您的函數應如下所示:
int load(Player *players, int max_players, int *player_count)
{
static const char filename[] = "players.txt";
FILE *file = fopen(filename, "r");
if (file != NULL)
{
char line[128];
while (!feof(file ) && !ferror(file )) /* read until end of file */
{
fscanf(file, "%d", &players[*player_count].played); // read played
fscanf(file, "%d", &players[*player_count].won); // read won
fscanf(file, "%d", &players[*player_count].lost); // read lost
fscanf(file, "%d", &players[*player_count].tie); // read tie
fscanf(file, "%d", &players[*player_count].points); // read points
fgets(line, sizeof line, file); // read new line
// increase player count
*player_count += 1;
}
fclose(file);
return 1;
}
return 0;
}
主要:
int main ()
{
Player players[MAX_PLAYERS] = { NULL };
int playerCount = 0;
load(players, MAX_PLAYERS, &playerCount);
printf("");
}
以下建議的代碼:
main()
初始化指針 main()
的指針 stderr
的計划,然后退出 main()
中將所有分配的內存指針傳遞給free()
以避免內存泄漏 現在,建議的代碼修改如下:
regarding:
typedef struct
{
char name[31];
int played;
int won;
int lost;
int tie;
int points;
} Player;
this anonymous struct will be very difficult to display
the individual fields via a debugger,
because debuggers use the 'tag' name of the struct
to reference the individual fields
in main function: Notice only declaring a pointer initialized to NULL,
then passing the address of the pointer to the function: `load()`
Player *players = NULL;
int playerCount = 0;
load(&players, &playerCount);
notice the double '**' on the 'players' parameter
This enables the sub function to modify the pointer field in the caller
int load(Player **players, int *player_count)
{
static const char filename[] = "players.txt";
// it is poor programming practice to name a variable the
// same as a struct, so changed `file` to `fp`
FILE *fp = fopen(filename, "r");
if( !fp )
{
perror( "fopen to read players.txt failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
// increased the size of the input buffer `line[]` for safety
char line[1024];
// note: used `calloc()` so when cleaning up from error
// no need to check if a specific entry in the 'player'
// array is used. `free()` handles a NULL parameter just fine
*players = calloc( MAX_PLAYERS, sizeof(Player*) );
if( !*players )
{
perror( "calloc for array of pointers to players failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
/* read until end of file or array full*/
while (*player_count < MAX_PLAYERS && fgets(line, sizeof line, fp))
{
(*players)[*player_count] = malloc(sizeof(Player));
if( !(*players)[ *player_count ] )
{
perror( "malloc for individual player failed" );
for( int i=0; i<MAX_PLAYERS; i++ )
{
free( (*players)[i] );
}
free( *players );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
if( sscanf( line, "%d %d %d %d %d",
players[*player_count]->played, // read played
players[*player_count]->won, // read won
players[*player_count]->lost, // read lost
players[*player_count]->tie, // read tie
players[*player_count]->points) != 5 ) // read points
{
fprintf( stderr, "extraction of player fields failed\n" );
exit( EXIT_FAILURE );
}
// increase player count
(*player_count) += 1;
}
fclose(file);
return 0;
}
int func(int ***players){
*players=new int* [MAXSIZE];
//use this if use c
// *players=(int**)malloc(sizeof(int*)*MAXSIZE);
for(int i=0;i<MAXSIZE;i++){
*(*players+i)=new int[2];
// *(*players+i)=(int*)malloc(sizeof(int)*2);
//2 is test can choose every number if your computer allow
}
}
並且您主要的應該喜歡這個主要的:
int main(){
int **players=nullptr;
func(&players);
//use follow if you must delete
for(int i=0;i<MAXSIZE;i++){
delete players[i];
}
delete players;
return 0;
}
typedef struct { int played;} Player;
void load(Player* &players, int max_players, int &player_count)
{
players = (Player*)malloc(max_players * sizeof(Player));
for (int i = 0; i < max_players; i++)
{
players[i].played = i;
player_count++;
}
}
int main()
{
const int MAX_PLAYERS=3;
Player* players= NULL ;
int playerCount = NULL;
load(players, MAX_PLAYERS, playerCount);
//...
free(players);
}
typedef struct Foo {
int x;
} Foo;
function:
void f(Foo **foo) {
foo[0]->x = 2021; // already allocate in main
foo[1] = malloc(sizeof(Foo)); // not locate yet
foo[1]->x = 2022;
}
int main() {
Foo **foo = malloc(100 * sizeof(Foo *)); // foo[10]
foo[0] = malloc(sizeof(Foo)); // must allocate before using
foo[0]->x = 2020; // assing 2021 to foo[0].x must use arrow for pointer
f(foo);
foo[1]->x = 2024; // already allocate in function f();
printf("main: value of x: %d\n", foo[0]->x);
printf("main: value of x: %d\n", foo[1]->x);
}
$ gcc test.c && ./a.out
value of x: 2021
value of x: 2024
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.