Go骰子游戏方法引发堆内存问题及总分计算异常求助
Troubleshooting Your Dice Game in Go: Fixing Zero Score & Heap Exhaustion
Hey there! Let's break down your two main issues step by step—why your total score stays stuck at 0, and how to fix the heap memory exhaustion problem.
1. Why Your Total Score Always Shows 0
This is almost always a variable scoping or value/pointer mistake. Here are the most common culprits and fixes:
Possible Causes
- Value instead of pointer passing: If your score-update function takes an
intinstead of*int, you're modifying a copy of the score, not the original variable. The original total stays 0 because the change never propagates back. - Broken roll-check logic: Maybe your condition for detecting 5s or 10s is incorrect (e.g., typos like
roll == 1instead ofroll ==5, or a missing||between the two checks). - Accidental reinitialization: If you're declaring the total score variable inside your game loop, it gets reset to 0 every iteration—so all previous progress is lost.
Fixes to Try
- Use pointers for score updates: Rewrite your score-update function to accept a pointer to the total score. For example:
Call it withfunc addToScore(total *int, roll int) { if roll == 5 || roll == 10 { *total += roll // Modify the original variable via pointer } }addToScore(¤tTotal, rollValue)to ensure changes stick. - Validate your roll-check logic: Add debug prints to confirm when 5s/10s are detected:
This will tell you if your condition is actually triggering when it should.for _, roll := range diceRolls { fmt.Printf("Checking roll: %d | Should add? %t\n", roll, roll ==5 || roll ==10) if roll ==5 || roll ==10 { // Add to score } } - Check score initialization: Make sure your total score variable is declared outside the game loop. For example:
func main() { totalScore := 0 // Initialize once, before the loop for totalScore < 500 { // Roll dice, update score, etc. } }
2. Fixing Heap Memory Exhaustion
Heap exhaustion usually comes from memory leaks, infinite loops, or unnecessary repeated memory allocation. Here's how to tackle it:
Possible Causes
- Infinite game loop: If your exit condition (total score >=500) is broken, the loop runs forever, allocating memory for dice rolls nonstop until the heap is full.
- Unnecessary memory allocation: If you're creating a new dice slice (or other large structures) every single roll without reusing existing memory, the garbage collector can't keep up with the constant new allocations.
- Hidden memory leaks: Maybe you're storing every single dice roll in a global slice or long-lived struct that never gets cleared, so memory keeps piling up.
Fixes to Try
- Verify your loop exit condition: Double-check that your loop correctly exits when the total hits 500. For example, if you accidentally wrote
totalScore >500instead oftotalScore <500, the loop will run forever. - Reuse memory for dice rolls: Instead of creating a new slice every time you roll, initialize one slice once and update its values on each roll. This cuts down on repeated allocations:
Even better, pass the slice into the roll function to avoid returning a new one each time:func rollDice() []int { // Initialize the slice once (or pass it in to reuse) dice := make([]int, 5) for i := range dice { dice[i] = getCustomRoll() // Replace with your custom dice logic } return dice }func rollDiceInto(dice []int) { for i := range dice { dice[i] = getCustomRoll() } } - Profile memory usage with
pprof: Use Go's built-in profiling tools to find exactly where memory is being stuck. Run your game with:
Then analyze the profile with:go run -memprofile mem.prof your_game.go
This will show you which functions are allocating the most memory, making it easy to spot leaks or wasteful allocations.go tool pprof mem.prof
Example Working Snippet
Here's a quick example tying these fixes together:
package main import ( "fmt" "math/rand" "time" ) // Custom dice roll logic (replace with your own) func customRoll() int { rand.Seed(time.Now().UnixNano()) return rand.Intn(10) + 1 // 1-10 range } // Roll dice into a pre-allocated slice to save memory func rollDice(dice []int) { for i := range dice { dice[i] = customRoll() } } // Update score using a pointer to modify the original value func updateScore(total *int, dice []int) { for _, roll := range dice { if roll == 5 || roll == 10 { *total += roll } } } func main() { totalScore := 0 // Pre-allocate dice slice once dice := make([]int, 5) for totalScore < 500 { rollDice(dice) fmt.Printf("Rolled: %v\n", dice) updateScore(&totalScore, dice) fmt.Printf("Current Total: %d\n", totalScore) time.Sleep(100 * time.Millisecond) // Slow down for readability } fmt.Printf("Game Over! You reached %d points!\n", totalScore) }
内容的提问来源于stack exchange,提问作者Destiny Coots
相关产品推荐
相关产品推荐

