RNG崩溃c++程序

RNG crashing c++ program

本文关键字:程序 c++ 崩溃 RNG      更新时间:2023-10-16

我目前正在编写一款roguelike游戏,自然会使用大量随机数生成。

我遇到的问题是,如果我"过热"rand();我的程序要崩溃了。

如果我每帧只生成20个左右的整数,这是好的…但是当随机数达到数百时,程序就会崩溃。我制作的每一帧越多,崩溃的速度就越快……这让我相信发生了连环车祸。

我已经做了测试,在20 rand();每帧调用一次,它将以最高速度连续运行24小时而不会崩溃。再加三倍,还不到十分钟。

如果我输入and();在初始化过程中,我可以在它被锁定之前生成数千个随机数-但是如果我使用srand();在帧本身内,我将其设置为2-8帧。如果这很重要,我将使用time(null)来播种。

越频繁地调用rand();它越早崩溃。

帮助吗?

rand()函数不是可重入的,也不是线程安全的,因为它使用的隐藏状态在每次调用时都会被修改。这可能只是的种子值在下次电话中使用,或者可能是更复杂的东西。为了在线程应用程序中获得可再现的行为,此状态必须他说得很清楚。函数rand_r()提供了一个指向unsigned int的指针,用作状态。这是一个非常小的状态,所以这个函数将是一个弱伪随机生成器。试试drand48_r(3)

关于如何缩小问题来源的一些意见和想法:

  • 它几乎肯定不是srand()rand()函数导致崩溃/锁定。很有可能是一个或多个随机数的组合会让你的引擎进入一个坏事情发生的状态。
  • 第一步应该是重复问题,这样它总是在同一时间/地点发生。而不是使用srand(NULL)尝试使用一个恒定的种子,如srand(12345)。根据你的引擎使用的其他因素(如用户输入),这可能足以让它每次在同一地点崩溃。
  • 如果使用调试器有问题(这是可疑的,可能是缓冲区溢出损坏了堆栈),请使用可靠的方法将消息输出到文本日志文件。我建议输出所生成的所有随机数,也许您可以在崩溃时看到一个模式(即,每当生成"42"时它就会崩溃)。另一个选择是开始在各种功能中添加一些日志信息(从游戏更新循环等高级功能开始)。崩溃后检查日志并开始添加更多的日志消息,直到将其缩小到一行/一个函数。这没有使用调试器那么快,但有时是一个更好的选择,特别是如果你真的不知道从哪里开始查找。
  • 一旦你能够可靠地复制崩溃开始删除东西,直到崩溃点改变或消失。这可能涉及#ifdef、注释代码、设置应用程序选项,甚至创建项目的临时副本,以便您可以简单地删除代码、编译和测试。如果项目大/复杂,这可能会很困难。
  • 更多关于"崩溃"类型的信息将会有所帮助。通常情况下,程序不会一般性地崩溃,而是会出现某些异常、锁定等....异常详细信息可以帮助您通过一些努力缩小问题的来源。

尝试在调试器下运行

$ gdb myprog
(gdb) break main
(gdb) run
(gdb) record

(gdb) break abort
(gdb) break exit

,因为它是c++:

(gdb) catch throw
(gdb) catch exception

最后(gdb)继续

当它停止时,反向继续,直到找到罪魁祸首


选项2:

valgrind --tool=massif --massif-out-file="massif.out.%p" myprog
ms_print massif.out.*

检查堆分析。不太可能出现内存泄漏

对rand的大量调用可能会出现一个相对较小的范围内的数字,而您的代码无法处理。试着用一个只增加数字并返回它的函数来替换对rand的调用,看看它最终是否会失败。

    你可能不应该使用rand()。市面上有更好的prng。看看Boost.Random.
  1. 你应该只登陆()一次,而不是每一帧。
  2. 找出代码崩溃的地方。使用调试器是相当容易的,只要启动附带调试器的程序,然后等待,直到它崩溃。
  3. 当你找到它崩溃的地方,找出它崩溃的原因。
  4. 当你找到原因后,修复它。它可能与rand()没有任何关系。