【问题标题】:Valgrind: Conditional jump or move depends on uninitialised value(s)Valgrind:有条件的跳转或移动取决于未初始化的值
【发布时间】:2016-09-03 10:29:37
【问题描述】:

Valgrind 给了我 有条件的跳转或移动取决于未初始化的值和 未初始化的值是由堆分配创建的 我当前代码的错误:

    void createMonsters(Game *game) {
       (void) game;

       Creature *nr;

       int x = 0;
       int r = 0;
       int y = 0;
       int check = 0;
       int c = game->opts.numMonsters;
       int nrm=0;


       nr=malloc( sizeof (Creature) * c);


        for(int i=0;i<c;i++){

            game->numMonsters=nrm;
            r = rand()%2;
            x = rand() % game->opts.mapWidth;
            y = rand() % game->opts.mapHeight;
            check=1;

            while(check!=2){
                check = isBlocked(game,x,y);
                if(check==1){
                    x = rand() % game->opts.mapWidth;
                    y = rand() % game->opts.mapHeight;
            }
                else{

                    nr[i].pos.y=y;
                    nr[i].pos.x=x;
                    nr[i].attack=attackPunch;
                    nrm += 1;
                    check=2;
            }
        }

            if(r==0){
                nr[i].name[0] = 'C';
                nr[i].maxhp = 15;
                nr[i].hp = nr[i].maxhp;
                nr[i].sign = 'C';
        }
            else{
                nr[i].name[0] = 'D';
                nr[i].maxhp = 50;
                nr[i].hp = nr[i].maxhp;
                nr[i].sign = 'D';


        }    

            game->monsters=nr;

        }
       game->numMonsters=nrm;
    }


int isBlocked(Game *game, int x, int y)
    {
            (void) game;
            (void) x;
            (void) y;
            if(x>game->opts.mapWidth || y>game->opts.mapHeight){
                return 1;
            }        }

            if(game->numMonsters!=0){                   
            for (unsigned int i = 0; i < game->numMonsters; i++){
                Creature *monst = &game->monsters[i];
                if (monst->pos.x == x && monst->pos.y == y){
                    return 1;
                }}
            }



            if(game->map.tile[y][x]==TILE_OPEN || game->map.tile[y][x]==TILE_ROOM){
                return 0;
            }
            else{
                return 1;
            }

     }

Valgrind 指向 nr=malloc( sizeof (Creature) * c); 那么我做错了什么?

    typedef struct creature_st {
        char name[20];  // name of the monster
        char sign;  // character that represents monster on the game display
        Point pos;  // location of the monster
        float hp;  // current hitpoints
        unsigned int maxhp;  // maximum hitpoints
        void (*move)(struct game_st *, struct creature_st *);  // current movement algorithm for monster
        void (*attack)(struct game_st *, struct creature_st *);  // current attack algorithm for monster
    } Creature;

完整的 valgrind 错误:

==386== 有条件的跳转或移动取决于未初始化的值 ==386==    在 0x4C2C1B8: strlen (在 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==386==乘0x403F54:test_createmonsters(test_source.c:179)== 386 == by 0x409377:srunner_run(/ tmc / test / test)== 386 == by 0x4057c9:tmc_run_tests(tmc-check.c:134)== 386 ==    通过 0x405464:main (test_source.c:529) ==386==  未初始化的值 是由堆分配创建的 ==386==    在 0x4C28C20: malloc (在 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux 中。所以)== 386 ==×44026C2:createmonsters(monster.c:288)== 386 == by 0x403adf:test_createmonsters(test_source.c:119)== 386 == by 0x409377:srunner_run(在/ tmc / test /测试)== 386 ==×0x4057C9:TMC_RUN_TESTS(TMC-CHECK.c:134)== 386 == 0x405464:main(test_source.c:529)== 386 ==

    typedef struct game_st {
        Map map;
        unsigned int numMonsters;  // number of elements in 'monsters' array
        Creature *monsters;  // dynamic array of all monsters
        Point position;  // current position of the player
        float hp;  // hit points, should never be higher than 'maxhp'
        unsigned int maxhp;  // maximum hit points
        Options opts;
    } Game;

【问题讨论】:

  • 这里的生物是完整的类型吗?如果这是结构上的 typedef,是否包含它的定义?
  • 添加了生物结构的定义
  • 我要问的是该文件是否有权访问该结构的定义?
  • 哦,是的,它可以访问 def。
  • 在这样的上下文中,您应该真正显示来自valgrind 的完整错误消息。诸如检测到问题的堆栈跟踪以及它通过的任何先前的 cmets 之类的东西可能是相关的。至少,在没有看到valgrind 跟踪的情况下,我不会试图猜测你做错了什么。 game-&gt;opts.numMonsters 的值是多少?如果valgrind 等到您分配内存来报告问题,这有点令人惊讶,但这用于确定c。还要考虑创建 MCVE (minimal reproducible example) 的技术。将这些原则应用于您的代码可能会有所帮助。

标签: c valgrind


【解决方案1】:

在您的代码中某处创建了未初始化的值,并且该函数访问该值。对 valgrind 使用 --track-origins=yes 选项来跟踪该值的来源。

【讨论】:

    猜你喜欢
    • 2011-04-18
    • 2016-07-24
    • 2014-11-30
    • 2014-04-07
    • 1970-01-01
    • 2019-08-14
    相关资源
    最近更新 更多