C语言 从struct的指针数组成员返回错误的数据(垃圾或0)



我正在尝试将一些float值作为数组读取到struct成员,如下所示:

#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <stdio.h>
#define MAX_IN 10
typedef struct S_t S_t;
struct S_t {
float *sptr; 
uint32_t ns;
};

S_t *getInputS(char *sdfile) 
{
FILE *inSFP;
float fvls[MAX_IN];
static S_t inS;
int n;
inSFP = fopen(sdfile, "r");
if (inSFP == NULL) {
printf("nFailed to open input file...!!!n");
}
else {
n = 0;
while (fscanf(inSFP, "%f", &fvls[n]) != EOF) {
printf("fvls[%d] = %fn", n, fvls[n]);
n++;
}
printf("nScanned all inputs....n");
inS.ns = (uint32_t) n;
inS.sptr = (float *) malloc(n * sizeof(float));
inS.sptr = fvls;
for(int i = 0; i < n; i++)
printf("inS.sptr[%d] = %fn", i, inS.sptr[i]);
printf("nInput read from file %s....n", sdfile);
fclose(inSFP);
printf("nClosed file...");
}
return &inS;
}

int main(int argc, char *argv[]) 
{
S_t *inpS = malloc(sizeof(*inpS));
inpS->sptr = malloc(MAX_IN * sizeof(inpS->sptr));
S_t *outS = malloc(sizeof(*outS));
outS->sptr = malloc(MAX_IN * sizeof(outS->sptr));
static uint32_t n;
char *inFN = argv[1];
char *outFN = argv[2];
inpS = getInputS(inFN);
printf("nContent from main : n");
n = inpS->ns;
for(int i = 0; i < n; i++)
printf("%f", *(inpS->sptr + i));
// printf("%f", inpS->sptr[i]);
printf("nS structure updated (ns = %d)....n", n);
return 0;
}

返回以下内容:

fvls[0] = 0.430000
fvls[1] = 0.563210
fvls[2] = 0.110000
fvls[3] = 1.230000
fvls[4] = -0.034000
Scanned all inputs....
inS.sptr[0] = 0.430000
inS.sptr[1] = 0.563210
inS.sptr[2] = 0.110000
inS.sptr[3] = 1.230000
inS.sptr[4] = -0.034000
Input read from file in.txt....
Closed file...
Content from main :
-0.0000000.0000000.0000000.000000-nan
S structure updated (ns = 5)....
Input values (Original Input):
[0.000000, 0.000000, -0.000000, 0.000000, -0.000000]

函数getInputS()正确地从输入文件中读取值,但是返回成员sptr时返回的值不正确。我使用类型S_t的静态变量来存储值,以便保留值。尽管如此,价值观似乎已经失去了!我哪里做错了?我该如何解决这个问题?

这一行:

inS.sptr = (float *) malloc(n * sizeof(float));

您将使sptr指向一个大小与您的输入正好合适的malloed区域。这很好。但是在下一行:

inS.sptr = fvls;

你扔掉malloc'ed指针,用一个指向本地fvls数组的指针覆盖它,当这个函数返回时,它将消失。

的另一种说法是:当您将指针存储在指针变量中时,就像将任何其他值存储在任何其他变量中一样。任何时候你做这样的事情:

a = b;
a = c;

你扔掉了第一次赋值的效果,当你完成后,所有a保留的是c的值。当a是指针变量,bc是两个不同的指针值时,这是没有区别的。

无论何时使用指针,都必须清楚地记住指针指针指向的对象之间的区别。在你的getInputS函数,你必须担心这两个:你必须设置指针sptr指向有效的存储来包含你读的值,你必须设置什么指针指向是那些值。当你说

inS.sptr = (float *) malloc(n * sizeof(float));

你正在设置指针。但是当你说

inS.sptr = fvls;

你正在重置指针到其他东西。但是,您根本没有时间设置指针指向的(即第一个malloc指针)。

和,为了清楚,行

inS.sptr = fvls;

复制指针,它不复制所指向的数据,而这正是您现在所需要的。

要解决这个问题,可以:

  1. fvls的数据拷贝到sptr(代替inS.sptr = fvls行)。您可以调用memcpy,也可以使用循环重复分配sptr[i] = fvls[i]
  2. 去掉fvls,初始化sptrmalloc(MAX_IN * sizeof(float));,直接读入sptr,然后在最后,如果你想尽量减少浪费的空间,调用realloc重新分配sptr,使其足够大,以满足你实际读取的值的数量。

最新更新