将数据动态添加到指向函数内结构的指针数组
Add data dynamically to array of pointers to structures within function
我尝试了很多组合,但都没有奏效。好久没来了,决定写这期。
我只想要一个指向结构的指针数组,以便以后可以通过交换地址轻松地对其进行排序。我有一个函数可以从文件中获取数据并写入数组。不幸的是,我不可能在函数外读取这些数据。
我最后一次尝试(我删除了文件操作,因为这些不是问题所在):
Header.h:
#pragma once
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int32_t year;
uint16_t month;
uint16_t day;
} Date;
typedef struct {
char name[16];
Date date;
uint32_t number;
} Player;
size_t readData(Player** players);
Source.c:
#include "Header.h"
size_t readData(Player** players) {
players = NULL;
players = realloc(players, sizeof(Player*) * 1);
players[0] = malloc(sizeof(Player));
strcpy(players[0]->name, "asd");
printf("$ %s\n", players[0]->name);//OK
return 1;
}
int main() {
Player **players = NULL;
uint32_t elemCount, i;
elemCount = readData(players);
printf("> %s", players[0]->name);//BUM - ERROR!
return 0;
}
我正在使用 Visual Studio Community 2015。我知道用 C 编写代码并不是那么重要,但我设法配置了解决方案,我觉得这似乎不是问题。
非常感谢您的帮助。然而,我希望将其视为对我的代码的重制。我像这样尝试了一些关于 Whosebug 问题的其他答案,但它们没有帮助。
如果函数的参数不仅被读取而且还应该作为输出,则必须将指向数据的指针传递给函数。如果您的数据类型是 Player**
,您的参数类型必须是 Player ***
,所以玩家列表本身可以在函数内部更改。
size_t readData(char* fname, Player*** players) {
// ^ players is a input and output parameter
Player **tempPlayers = *players; // local list of players
tempPlayers = realloc(tempPlayers, sizeof(Player*) * 1);
tempPlayers[0] = malloc(sizeof(Player));
strcpy(tempPlayers[0]->name, "asd");
printf("$ %s\n", tempPlayers[0]->name);//OK
*players = tempPlayers; // write back list of players to paramter
return 1;
}
int main() {
Player **players = NULL;
uint32_t elemCount, i;
char *fileName = NULL;
elemCount = readData(&players);
// ^
printf("> %s", players[0]->name);//BUM - ERROR!
return 0;
}
如果你不想使用 ***
你可以这样做:
Player* *readData(char* fname, Player** players, size_t *size) {
players = realloc(players, sizeof(Player*) * 1);
players[0] = malloc(sizeof(Player));
strcpy(players[0]->name, "asd");
printf("$ %s\n", players[0]->name);//OK
*size = 1;
return players;
}
players = readData( fileName, players, &elemCount );
您通过 value 将指针传递给函数; main
中原来的players
没变。这与做没有什么不同:
#include <stdio.h>
void func(int x)
{
x = 4;
}
int main()
{
int x = 0;
func(x);
printf("%d\n", x); // zero
}
我假设是指针让您感到困惑,所以您现在应该明白您的错误了。
要使修改在 readData
之外可见,您需要使用三个间接级别:
size_t readData(Player*** players) {
*players = malloc(sizeof(Player*) * 1);
*(players)[0] = malloc(sizeof(Player));
strcpy((*players)[0]->name, "asd");
printf("$ %s\n", (*players)[0]->name);//OK
return 1;
}
int main() {
Player **players = NULL;
uint32_t elemCount, i;
elemCount = readData(&players);
printf("> %s", players[0]->name); // prints 'asd'
return 0;
}
当您 知道 传递的指针始终是 NULL
时,使用 realloc
没有意义,所以我将其更改为 [=17] =] 代替。
附带说明:Visual Studio 非常适合 C 开发,并实现了 C99 甚至 C11 的部分功能(历史上 MSVC 始终停留在 C89)。您可以只为您的源文件使用 .c
扩展名,这将使编译器假定代码是 C,或者您可以在 属性 页面中明确设置它。
传递给 readData() 的参数必须是调用者指针的地址 'players'
readData() 中对 players
的每个引用都必须考虑到这一点。
否则调用者的指针'player'将不会更新。
然后 main() 函数调用 printf() 试图从地址 0 输出,导致未定义的行为,导致段错误事件。
在 main() 函数中,如果你插入:
printf( "player value; %p\n", (void*)players);
在当前调用 printf() 之前,您会看到 players
指针仍然包含 NULL。
我尝试了很多组合,但都没有奏效。好久没来了,决定写这期。
我只想要一个指向结构的指针数组,以便以后可以通过交换地址轻松地对其进行排序。我有一个函数可以从文件中获取数据并写入数组。不幸的是,我不可能在函数外读取这些数据。
我最后一次尝试(我删除了文件操作,因为这些不是问题所在):
Header.h:
#pragma once
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int32_t year;
uint16_t month;
uint16_t day;
} Date;
typedef struct {
char name[16];
Date date;
uint32_t number;
} Player;
size_t readData(Player** players);
Source.c:
#include "Header.h"
size_t readData(Player** players) {
players = NULL;
players = realloc(players, sizeof(Player*) * 1);
players[0] = malloc(sizeof(Player));
strcpy(players[0]->name, "asd");
printf("$ %s\n", players[0]->name);//OK
return 1;
}
int main() {
Player **players = NULL;
uint32_t elemCount, i;
elemCount = readData(players);
printf("> %s", players[0]->name);//BUM - ERROR!
return 0;
}
我正在使用 Visual Studio Community 2015。我知道用 C 编写代码并不是那么重要,但我设法配置了解决方案,我觉得这似乎不是问题。
非常感谢您的帮助。然而,我希望将其视为对我的代码的重制。我像这样尝试了一些关于 Whosebug 问题的其他答案,但它们没有帮助。
如果函数的参数不仅被读取而且还应该作为输出,则必须将指向数据的指针传递给函数。如果您的数据类型是 Player**
,您的参数类型必须是 Player ***
,所以玩家列表本身可以在函数内部更改。
size_t readData(char* fname, Player*** players) {
// ^ players is a input and output parameter
Player **tempPlayers = *players; // local list of players
tempPlayers = realloc(tempPlayers, sizeof(Player*) * 1);
tempPlayers[0] = malloc(sizeof(Player));
strcpy(tempPlayers[0]->name, "asd");
printf("$ %s\n", tempPlayers[0]->name);//OK
*players = tempPlayers; // write back list of players to paramter
return 1;
}
int main() {
Player **players = NULL;
uint32_t elemCount, i;
char *fileName = NULL;
elemCount = readData(&players);
// ^
printf("> %s", players[0]->name);//BUM - ERROR!
return 0;
}
如果你不想使用 ***
你可以这样做:
Player* *readData(char* fname, Player** players, size_t *size) {
players = realloc(players, sizeof(Player*) * 1);
players[0] = malloc(sizeof(Player));
strcpy(players[0]->name, "asd");
printf("$ %s\n", players[0]->name);//OK
*size = 1;
return players;
}
players = readData( fileName, players, &elemCount );
您通过 value 将指针传递给函数; main
中原来的players
没变。这与做没有什么不同:
#include <stdio.h>
void func(int x)
{
x = 4;
}
int main()
{
int x = 0;
func(x);
printf("%d\n", x); // zero
}
我假设是指针让您感到困惑,所以您现在应该明白您的错误了。
要使修改在 readData
之外可见,您需要使用三个间接级别:
size_t readData(Player*** players) {
*players = malloc(sizeof(Player*) * 1);
*(players)[0] = malloc(sizeof(Player));
strcpy((*players)[0]->name, "asd");
printf("$ %s\n", (*players)[0]->name);//OK
return 1;
}
int main() {
Player **players = NULL;
uint32_t elemCount, i;
elemCount = readData(&players);
printf("> %s", players[0]->name); // prints 'asd'
return 0;
}
当您 知道 传递的指针始终是 NULL
时,使用 realloc
没有意义,所以我将其更改为 [=17] =] 代替。
附带说明:Visual Studio 非常适合 C 开发,并实现了 C99 甚至 C11 的部分功能(历史上 MSVC 始终停留在 C89)。您可以只为您的源文件使用 .c
扩展名,这将使编译器假定代码是 C,或者您可以在 属性 页面中明确设置它。
传递给 readData() 的参数必须是调用者指针的地址 'players'
readData() 中对 players
的每个引用都必须考虑到这一点。
否则调用者的指针'player'将不会更新。
然后 main() 函数调用 printf() 试图从地址 0 输出,导致未定义的行为,导致段错误事件。
在 main() 函数中,如果你插入:
printf( "player value; %p\n", (void*)players);
在当前调用 printf() 之前,您会看到 players
指针仍然包含 NULL。