【问题标题】:Different outputs for different number of printf calls不同数量的 printf 调用的不同输出
【发布时间】:2019-06-14 22:26:56
【问题描述】:

我是 C 的新手,我的代码有一个奇怪的问题。

我正在尝试创建一个 struct 数组作为另一个 struct 数组的一部分。

printf 函数的数量不同时,我得到不同的输出。我有两种情况,一种是正确的,另一种是错误的。

我不明白为什么一个额外的printf 的简单调用会改变结果。

这是我的代码,结果不正确,这里我得到“x velocity=-nan”

#include<stdlib.h>
#include<stdio.h>

struct vect3d1
{
    double *x,*y,*z;
};

struct block
{ 
   int ibl;
   struct vect3d1 *velocity;
};

void create_time(struct block *blocks,int Nsteps,int nb);


int main()
{

struct block *blocks;
int nb,i,t,Nsteps;
Nsteps=30;
nb=3;
blocks=calloc(nb, sizeof(struct block));
for (i=0;i<nb;i++){
        for(t=0;t<Nsteps;t++){

blocks[i].velocity=(struct vect3d1 *)malloc(Nsteps*sizeof(struct vect3d1));
blocks[i].velocity[t].x=NULL;
blocks[i].velocity[t].y=NULL;
blocks[i].velocity[t].z=NULL;

}
}

create_time(blocks,Nsteps,nb);

free(blocks);
}

void create_time(struct block *blocks,int Nsteps,int nb){

int i,t;
double u;

for (i=0;i<nb;i++){
    for(t=0;t<Nsteps;t++){
        u=0.5+t;
        blocks[i].velocity[t].x=&u;
//          printf("u %lf \n",u);
        printf("velocity x=%lf \n",blocks[i].velocity[t].x);

}
}


}

你可以注意到函数create_time中的一行被注释了,当它没有被注释时结果是正确的。

只是为了澄清,如果函数create_time是:

void create_time(struct block *blocks,int Nsteps,int nb){

int i,t;
double u;

for (i=0;i<nb;i++){
    for(t=0;t<Nsteps;t++){
        u=0.5+t;
        blocks[i].velocity[t].x=&u;
//          printf("u %lf \n",u);
        printf("velocity x=%lf \n",blocks[i].velocity[t].x);

}
}


}

我得到:

"velocity x=-nan"

当函数为:

void create_time(struct block *blocks,int Nsteps,int nb){

int i,t;
double u;

for (i=0;i<nb;i++){
    for(t=0;t<Nsteps;t++){
        u=0.5+t;
        blocks[i].velocity[t].x=&u;
            printf("u %lf \n",u);
        printf("velocity x=%lf \n",blocks[i].velocity[t].x);

}
}


}

我得到:

"u 0.5"

"velocity x=0.5"
...

等等。

我添加该行只是为了验证变量u,然后我意识到添加它会更改printf 的输出。

发生了什么?为什么printf的输出变了?

【问题讨论】:

  • x 是一个指针double *x。你需要尊重它。 *blocks[i].velocity[t].x); 。打开编译器警告并解决每个警告。
  • blocks[i].velocity 分配应该在t 循环之外。
  • 感谢您的建议。

标签: c struct printf malloc nan


【解决方案1】:

这里

  printf("velocity x=%lf \n",blocks[i].velocity[t].x);

您没有传递一个double,而是一个指向double 的指针,尽管应该传递一个double。这调用了臭名昭著的未定义行为。不要这样做。

我也想知道为什么编译器没有警告你这个。您可能想提高编译器的衰减水平。对于 GCC,在编译时添加选项 -Wall -Wextra -pedantic

要修复此更改

  printf("velocity x=%lf \n", *blocks[i].velocity[t].x);

所以回答你的问题:

发生了什么?为什么 printf 的输出会改变?

欢迎来到 Undefined Behaviour 的神秘世界。 ;)


除此之外,请注意这一行

  blocks[i].velocity[t].x=&u;

很危险,因为您将变量 local 的地址分配给函数的指针,该指针很可能会在函数离开后使用。

一旦函数离开,它确实不再指向有效内存。

取消引用然后会调用未定义的行为,小心。


作为最后的友好说明:请帮助您自己和您的程序员同行,他们必须阅读您的代码并正确缩进代码。这是免费调试。我有一个强烈的印象,this bug 归因于代码的凌乱缩进,如图所示。

【讨论】:

  • 非常感谢! :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 2023-03-08
  • 2015-02-15
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多