【问题标题】:uninitialized pointer of structure to the function指向函数的结构的未初始化指针
【发布时间】:2017-10-19 22:43:12
【问题描述】:

我正在尝试学习 C 编程,但是当我尝试将未初始化的结构指针传递给函数时遇到了困难。

这是我的结构:

typedef struct {
    char name[30];
    char surname[30];
    char gender;
    char DOB[10];
    int waist;
    int hip;
}healthcare_table;

我的主

int main() {
    healthcare_table *records;
    int step = 1;
    load_healthcare_table(records,&step);
    return 0;
}

我的函数将打开文件并根据文本文件中的行数初始化指针,但我做不到。有什么建议吗?

更新: 我正在犯这样的错误,我不知道出了什么问题。 错误消息是:在 ConsoleApplication1.exe 中的 0x00D7529C 处引发异常:0xC0000005:访问冲突读取位置 0x0000004C。

这是我更新后的代码:

typedef struct {
	char name[30];
	char surname[30];
	char gender;
	char DOB[10];
	int waist;
	int hip;
}healthcare_table;

void load_healthcare_table(healthcare_table **t, int *step) {
	int i;
	FILE *infile;
	infile = fopen("records.txt", "r");
	if (infile == NULL)
		printf("File not opened successfully");
	else
		printf("File opened successfully");
	for (i = 0; fscanf(infile, "%s %s %c %s %d %d", *t[*step]->name, *t[*step]->surname, t[*step]->gender, *t[*step]->DOB, t[*step]->waist, t[*step]->hip) != EOF; i++) {
		if (fgetc(infile) == '\n') {
			*step++;
			//*t = (healthcare_table*)realloc(*t, *step);
			//fprintf(infile, "%s %s %c %s %d %d", *t[*step]->name, *t[*step]->surname, t[i]->gender, *t[*step]->DOB, t[*step]->waist, t[*step]->hip);
		}
	}
	*t = (healthcare_table*)malloc((*step) * sizeof(healthcare_table));
	for (i = 0; fscanf(infile, "%s %s %c %s %d %d", *t[i]->name, *t[i]->surname, t[i]->gender, *t[i]->DOB, t[i]->waist, t[i]->hip) != EOF; i++) {
		if (fgetc(infile) == '\n')
			fprintf(infile, "%s %s %c %s %d %d", *t[i]->name, *t[i]->surname, t[i]->gender, *t[i]->DOB, t[i]->waist, t[i]->hip);
	}

}

void display_healthcare_table(healthcare_table *records) {
	
}

void search() {

}

void WHR_interpreter() {

}

int main() {
	healthcare_table *records=NULL;
	int step = 0;
		load_healthcare_table(&records, &step);
	return 0;

}

更新 2: 我认为问题是 fscanf 和 fprintf。如果我错了,我该如何解决?

【问题讨论】:

  • 开始正确地格式化这个烂摊子和minimal reproducible example
  • C 允许使用野指针,这是语言的一个缺陷。确保所有指针都为空或指向内存中的有效对象。

标签: c arrays pointers data-structures structure


【解决方案1】:

如果不想在主函数中分配指针,有两种可能的解决方案:

解决方案 1

不要将healthcare_table 指针传递给load_healthcare_table() 函数,而是从函数本身返回初始化的指针。大致如下:

int main() {
    healthcare_table *records;
    int step = 1;
    records = load_healthcare_table(&step);
    return 0;
}

在这种情况下,您的 load_healthcare_table() 函数将是:

healthcare_table* load_healthcare_table(int* step) {
    healthcare_table *table;
    table = (healthcare_table*)malloc(sizeof(healthcare_table));
    // Fill table here
    return table;
}

重要提示 在这种情况下,请确保您不要在本地为 load_healthcare_table() 函数创建表。一旦函数返回,这将破坏表,从而导致垃圾数据。函数永远不应返回指向其本地数据的指针。所以下面的例子是错误的

healthcare_table* load_healthcare_table(int* step) {
    healthcare_table table;
    // Fill table here
    return &table;
}

解决方案 2

将指向healthcare_table 的指针的指针传递给函数load_healthcare_table()。它看起来像这样:

int main() {
    healthcare_table *records;
    int step = 1;
    load_healthcare_table(&records,&step);
    return 0;
}

在这种情况下,load_healthcare_table() 函数将是:

void load_healthcare_table(healthcare_table** t, int* step ) {
    *t = (healthcare_table*)malloc(sizeof(healthcare_table));
    // Fill table here
}

编辑

正如 Ajay Brahmakshatriya 所建议的:坚持标准 C 的局部变量概念,而不是进入堆栈术语。

【讨论】:

  • @BrianZammit 在这种情况下,请确保不要在堆栈上创建表 C 标准没有说明堆栈。我认为您的意思是本地范围。
  • @Ajay Brahmakshatriya 正确。是的,这在 C 标准方面更合适。但是,编译后的代码(据我所知)会将这些变量放在堆栈上。每个调用的函数都将创建自己的堆栈帧,其中包含其局部变量。返回时,此堆栈帧被“销毁”并因此无效。它将被未来的堆栈帧覆盖,因此函数返回指向其局部变量的指针是不正确的
  • @BrianZammit 我不同意你的解释。但是您提到的是一种使用堆栈来存储局部变量的实现。可能有(并且是)许多根本不使用堆栈的实现。使用堆栈这个词可能会让人产生错误的想法,即这个问题仅适用于使用堆栈的实现,但实际上适用于所有人。
  • @Ajay Brahmakshatriya 感谢您的澄清。答案已相应编辑。我从未听说过不使用堆栈的实现。是否可以向我指出一些可以研究这种方法的资源?谢谢
【解决方案2】:

虽然将未初始化的指针传递给函数是没有用的,但传递未分配的指针可能很有用,只要:

  • 指针已被初始化为空指针。
  • 该函数要么使用realloc() 为指针重新分配内存,要么在使用malloc() 之前检查它是否为空指针。
  • 函数返回指针。

示例代码 sn-p(假设定义了结构体a_struct):

a_struct *a_funct(a_struct *p);
int main(void)
{
    struct a_struct *p_a_struct = NULL;
    p_a_struct = a_funct(p_a_struct);
    return 0;
}

a_struct *a_funct(a_struct *p)
{
    // Does some stuff to find how many records p should point to.
    p = realloc(p, sizeof a_struct * number_of_records);
    // Check p for error.
    // Do more stuff?
    return p;
}

或者你可以传递一个指向函数的指针,正如其他答案中提到的那样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 2021-10-27
    相关资源
    最近更新 更多