簡體   English   中英

rand()在valgrind中使用時會生成不同的值

[英]rand() generating different values when used in valgrind

我正在嘗試以尺寸為100x100的二維數組隨機生成房間。 如果正在生成的房間與現有房間發生沖突,則會為該房間生成新點。 生成代碼從概念上講是有意義的,但是當我嘗試運行時,該程序會無限循環,並檢查日志以了解原因。

Room created successfully with dimensions x=0, y=0, width=976761120, height=809120052

出於某種原因,在create_room()內部的65-68行中,正在為房間的寬度和高度隨機分配一個巨大的數字,當它們應該在1到11之間時。為了好玩,我使用了options --track-origins = yes -v,我發現我很驚訝。 突然,該程序將運行!

Room created successfully with dimensions x=0, y=0, width=0, height=0

雖然仍然不是我想要的,但這至少可以防止在不可能的巨大空間中檢測到無限的碰撞循環。

所以,我的問題是,為什么代碼正常執行時會生成這么大的數字,而在Valgrind中卻生成更小的數字?

這是程序的代碼。

#include <time.h>
#include <stdlib.h>
#include "global.h"
#include "draw.h"
#include "log.h"
#include "generate.h"
#define NUM_ROOMS 10
#define ROOM_SIZE 10
#define MAP_HEIGHT 100
#define MAP_WIDTH 100

static struct ROOM* create_room (unsigned int);

struct ROOM {
    int x, y, width, height; 
    int feature;
};

struct ROOM* rooms[NUM_ROOMS] = {NULL};

static FILE* gen_log;

static WINDOW* gen_window;

int** generate_dungeon(unsigned int seed){
    char* log_entry = malloc (80);
    int i = 0, j, k;
    gen_window = create_window (0, 0, LINES, COLS);

    gen_log = log_open (GEN_LOG);
    if (seed == 0){
        time_t t;
        seed = time (&t);
    }
    srand (seed); 
    for (int i = 0; i < NUM_ROOMS; i++){
        rooms[i] = create_room (seed);
        sprintf (log_entry,"Room created successfully with dimensions x=%d, y=%d, width=%d, height=%d\n", rooms[i]->x, rooms[i]->y, rooms[i]->width, rooms[i]->height);
        LOG_DEBUG (gen_log,log_entry);
    }
    LOG_DEBUG(gen_log, "Beginning to draw rooms\n");
    for (i=0;i < NUM_ROOMS;i++){
        sprintf (log_entry, "Drawing room %d\n", i);
        LOG_DEBUG (gen_log, log_entry);
        for (j = rooms[i]->y; j < rooms[i]->y + rooms[i]->height; j++){
            for (k = rooms[i]->x; k < rooms[i]->x + rooms[i]->width; k++){
                sprintf (log_entry, "Clearing %d,%d]\n", j,k);
                LOG_DEBUG (gen_log, log_entry);
                map_array[j][k] = 1;
            }
        }
    }
    destroy_window (gen_window);
}

static struct ROOM* create_room (unsigned int seed){
    int i = 0, flag; 
    srand (seed);
    if (rooms[0] == NULL)
        flag = 0;
    else
        flag = 1;
    char* log_entry = malloc (80);
    struct ROOM* new_room = malloc (sizeof(struct ROOM));
    while (flag){
        draw_notify (gen_window, "Creating room\n");
        new_room->x = (rand() % MAP_WIDTH);
        new_room->y = (rand() % MAP_HEIGHT);
        new_room->width =  (rand() % ROOM_SIZE + 1);
        new_room->height = (rand() % ROOM_SIZE + 1);

        sprintf (log_entry, "New room created with points x=%d, y=%d,width=%d, height=%d\n", new_room->x, new_room->y, new_room->width, new_room->height);
        LOG_DEBUG (gen_log, log_entry);
        draw_notify (gen_window, "Log entry made\n");

        if (new_room->x + new_room->width >= MAP_WIDTH || new_room->y + new_room->height >= MAP_HEIGHT){
            LOG_DEBUG (gen_log, "Room out of bounds\n");
            continue;
        }
        i=0;
        draw_notify(gen_window, "Entering loop\n");
        while (rooms[i] != NULL && i < NUM_ROOMS){
            sprintf (log_entry, "Testing room %d\n", i);
            draw_notify (gen_window, log_entry);
            LOG_DEBUG(gen_log, log_entry);
            if (new_room->x < rooms[i]->x + rooms[i]->width && 
                new_room->x + new_room->width > rooms[i]->x && 
                new_room->y < rooms[i]->y + rooms[i]->height &&
                new_room->y + new_room->height > rooms[i]->y){
                    sprintf (log_entry, "Collision detected with room %d\n", i);
                    draw_notify (gen_window, log_entry);
                    LOG_DEBUG (gen_log, log_entry);
                    flag = 1;
                    break;
            }
            else{
                sprintf (log_entry, "Room %d passed.\n", i);
                flag = 0;
                i++;
            }
        }
        draw_notify(gen_window, "Exited loop\n");
    }
    return new_room;
}

您會遇到一些邏輯錯誤,並最終得到未初始化的值。

您將rooms初始化為NULL指針的數組。

create_room ,您具有:

if (rooms[0] == NULL)
    flag = 0;
else
    flag = 1;

第一次, flag將設置為0 然后,您使用:

struct ROOM* new_room = malloc (sizeof(struct ROOM));
while (flag){

由於flag設置為0 ,因此while下的任何內容都不會執行,最終您會在new_room得到未初始化的成員。

您需要重新考慮自己的邏輯,並確保始終初始化new_room成員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM