Различные выходы для разного количества вызовов printf - PullRequest
0 голосов
/ 21 января 2019

Я новичок в C, и у меня странная проблема с моим кодом.

Я пытаюсь создать массив struct как часть другого массива struct.

Я получаю разные выходы, когда номер функции printf отличается. У меня есть два случая, один правильный, а другой неправильный.

Я не понимаю, почему простой вызов дополнительного printf должен изменить результат.

Это мой код с неверным результатом, здесь я получаю "x speed = -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 меняется?

1 Ответ

0 голосов
/ 21 января 2019

Здесь

  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 меняется?

Добро пожаловать в таинственный мир неопределенного поведения. ;)


Кроме этого, имейте в виду, что эта строка

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

опасно, так как вы назначаете адрес переменной local для функции указателю, который, скорее всего, будет использоваться после того, как функция была оставлена.

Это не указывает на действительную память больше после того, как функция оставлена.

Разыменование затем вызовет неопределенное поведение, будьте осторожны.


В качестве заключительного дружеского замечания: Сделайте себе и своим коллегам-программистам, которые должны прочитать ваш код, услугу и правильно введите отступ . Это отладка бесплатно. У меня сложилось сильное впечатление, что эта ошибка связана с грязным отступом кода, как показано.

...