C - 结构到指针

标签 c pointers struct

当我从读取函数中打印时,会打印所有正确的值,但是当我返回计算机*时,大多数值会由于某种原因丢失。请注意,我无法更改函数头,也无法使用全局变量。

读取功能:

Computer* readComputers( char* filename ) {

FILE* fp = fopen( filename, "r" );

if( fp == NULL ) {
    printf( "Error: Invalid file!" );
    exit( 0 );
}

Computer computer[5];
Computer *compPtr;
int i;

for( i = 0; i < 5; i++ ) {
    fscanf( fp, "%s %i", computer[i].serialNumber, &computer[i].price );
    fscanf( fp, "%i %i", &computer[i].GBofRAM, &computer[i].GBofHardDrive );
    if( feof( fp ) ) {
        break;
    }
}

compPtr = &computer;

for( i = 0; i < 5; i++ ) {

/*
*   THIS WORKS TO PRINT OUT ANY VALUE I WANT USING THE POINTER
    printf( "%s\n", (compPtr + i)->serialNumber );
*/

}

fclose( fp );

return compPtr;

}

主函数(我将指针返回到的位置):

    Computer *computers;

    computers = readComputers( filename );

    for( i = 0; i < 5; i++ ) {
        printf( "%s\n", (computers + i)->serialNumber );  
    }

当我从 readComputers 返回指针时,这些值变得困惑,并且在尝试从主函数打印时消失。

最佳答案

您返回一个指向具有自动存储功能的结构的指针。该结构是存储在堆栈上的局部变量(很可能),并且在函数返回后不会保留。它会被 readComputers 返回后调用的其他函数的本地数据破坏。

这是一个非常基本的错误,编译器应该能够检测到,但没有检测到,要么是因为您没有要求足够的警告(尝试 gcc -Wall -W),要么是因为您返回了通过局部变量而不是数组本身的指针。

您可以通过分配使用 malloccalloc 返回的结构或使用外部存储并将指向该结构的指针传递给 readComputers 来纠正此问题>。第一种方法可以这样实现:

删除 computercompPtr 的定义并写入:

Computer *computer = calloc(sizeof(Computer), 5);

并返回computer而不是compPtr

您的代码中还存在其他令人不安的问题:使用 fscanf 解析输入是有风险的,因为该系列函数的语义很微妙且容易出错。例如:

fscanf( fp, "%s %i", computer[i].serialNumber, &computer[i].price );
  • 您不检查返回值,这是了解正确解析了多少字段的唯一可靠方法。
  • 您没有告诉fscanf数组computer[i].serialNumber的大小。读取无效的输入将导致未定义的行为,它可能会导致您的程序崩溃,甚至可能被攻击者用来控制程序/计算机...
  • 调用 fscanf 后对 feof(fp) 的检查不正确:它无法判断字段是否已正确解析。
  • 此外,您无法向调用者返回正确解析了多少个结构。您的 API 需要一些改进。

关于C - 结构到指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32684445/

相关文章:

c - 如何从c中的文件中读取带有空格、整数和浮点值的字符串?

c popen 不会捕获 stderr

c - 初始化指向整数数组的指针。

c - 尝试使用指针数组和冒泡排序编写数据排序程序,请帮忙

c - 使用结构时取消引用 'void *' 指针

c - 遍历多维数组并添加 float

c++ - 释放指针 vector 的两种不同方法——为什么一种方法不起作用?

struct - 如何在struct的方法中设置和获取字段

struct - Rust 中结构的字段可变性

c - ADC 不适用于 ATMEGA8