使用 DLL 和 C/C++ 命中断点时的不同结果

Different result when hitting breakpoints, using DLL and C/C++

我正在尝试使用 C/C++ 和我制作并隐式链接的 DLL 为学校开发一个小游戏。到目前为止,一切都很好。 现在我正在测试一些功能,当我 运行 一次所有代码或者我放置一个断点来停止代码时,我得到了不同的结果。

我会展示一些代码,我会尽力解释。

struct powerup get_powerup() {
struct powerup aux {};

srand(time(nullptr));
int r = rand() % 100 + 1; // random number between 1 and 100

if (r <= 60) //common
    aux.occurrence = common;
else if (r > 60 && r < 90) //rare
    aux.occurrence = uncommon;
else if (r >= 90) //very rare
    aux.occurrence = rare;

switch (aux.occurrence)
{
case common:
    r = rand() % 2 + 1;

    if (r == 1)
        aux = set_powerup(shield);
    if (r == 2)
        aux = set_powerup(enemy_boost);
    break;
case uncommon:
    r = rand() % 3 + 1;

    if (r == 1)
        aux = set_powerup(ice);
    if (r == 2)
        aux = set_powerup(battery);
    else if (r == 3)
        aux = set_powerup(alchool);
    break;
case rare:
    r = rand() % 2 + 1;

    if (r == 1)
        aux = set_powerup(life);
    if (r == 2)
        aux = set_powerup(noclip);
    break;
}

return aux;
}

这是我正在测试的功能,非常简单并且工作正常。

int _tmain(int argc, TCHAR *argv[]) {
#ifdef UNICODE
_setmode(_fileno(stdin), _O_WTEXT);
_setmode(_fileno(stdout), _O_WTEXT);
_setmode(_fileno(stderr), _O_WTEXT);
#endif
for (int i = 0; i < 10; i++)
{
    const struct powerup ajux = get_powerup();

    _tprintf(TEXT("power up: %hs\n"), powerup_type_string[ajux.type]);
}

system("Pause");

return 0;
}

这是我的主要代码。 现在是奇怪的部分,至少对我而言。在你说 "its because it's a random generator" 之前,稍等片刻。

当运行一次全部调用代码时,我每次都得到相同的结果:

power up: Enemy Boost
power up: Enemy Boost
power up: Enemy Boost
power up: Enemy Boost
power up: Enemy Boost
power up: Enemy Boost
power up: Enemy Boost
power up: Enemy Boost
power up: Enemy Boost
power up: Enemy Boost

但是如果在 for 循环中放置一个断点,我会得到预期的结果:

power up: Shield
power up: Battery
power up: Ice
power up: Alchool
power up: Alchool
power up: Battery
power up: No Clip
power up: Life
power up: Enemy Boost
power up: Enemy Boost

对此有何建议?

是的,这是因为随机生成器。

您正在 get_powerup 中调用 srand(time(nullptr))。 这意味着随机数生成器是从每次调用的当前时间开始播种的,并且由于 time 是第二个粒度,因此当您 运行 代码时,将显示为 return 相同的值。

srand 的想法是在应用程序启动期间仅调用一次以播种 PRNG。将其移动到 main 函数的开头。