计算3个骰子和≥k的概率时出现段错误问题求助
Let's break down what's going wrong with your code and fix it step by step:
1. The Root Cause of the Segmentation Fault
Your recursive approach calls cum_prob 10,000,000 times when trials is set to 1e7. Each recursive call creates a new stack frame (to store local variables, return address, etc.), and the program's call stack has a limited size (usually a few megabytes). This deep recursion causes a stack overflow, which triggers the segmentation fault.
Recursion is a terrible fit here—iterative loops are far more efficient for large numbers of repetitions like this.
2. Other Critical Logical Errors in Your Original Code
Even if the stack didn't overflow, your function wouldn't calculate the correct probability:
- Local variable reset on each recursion: Every time you call
cum_prob,countandall_trialsare reinitialized to 0. You never actually accumulate the total number of successful trials across iterations. - Incorrect dice sum generation:
rand() % 18 + 3generates a uniform random number between 3 and 18, but the sum of 3 dice is not uniformly distributed (e.g., sum=3 only has 1 possible combination, while sum=10 has 27). This would give you completely wrong probability values. - Wrong success condition: You check if the sum equals
k, but the problem asks for sums at least k (sum >= k). - Uninitialized variable: When
trials == 0, you returnprobwhich was never initialized—this is undefined behavior that could crash your program or return garbage values. - Unreachable code: The line
prob = ((count / all_trials) * 100);is never executed because you return before reaching it.
3. Fixed Iterative Implementation
Here's a corrected version of the cum_prob function that fixes all these issues:
double cum_prob(int k, long trials) { // Edge case: no trials means 0 probability if (trials == 0) { return 0.0; } long successful_trials = 0; for (long i = 0; i < trials; i++) { // Roll each die individually to get a realistic sum distribution int die1 = rand() % 6 + 1; int die2 = rand() % 6 + 1; int die3 = rand() % 6 + 1; int total = die1 + die2 + die3; // Count trials where sum is at least k if (total >= k) { successful_trials++; } } // Calculate probability as a double (cast to avoid integer division) return (double)successful_trials / trials; }
Key Improvements:
- Iterative loop: No stack overflow, even for extremely large
trialsvalues. - Accurate dice simulation: Each die is rolled separately, ensuring the sum follows the correct probability distribution for 3 dice.
- Proper accumulation:
successful_trialskeeps a running total of valid trials across all iterations. - Correct success condition: Checks
total >= kas required. - Safe edge case handling: Returns 0.0 when
trialsis 0, avoiding undefined behavior. - Type safety: Uses
longforsuccessful_trialsto prevent integer overflow with large trial counts.
4. Testing the Fixed Code
When you run this with n = 10000000, it will execute without segmentation faults and return the correct cumulative probability. For example, if you enter k=10, it should return a value close to the theoretical probability of ~70.37%.
内容的提问来源于stack exchange,提问作者Shahawn

