C语言Blackjack模拟程序指针异常求助:Read Access Violation(nullptr)
Hey there! Let's break down the issue you're facing with that Read Access Violation first—it's a super common pitfall when you're just starting out with pointers in C.
The Core Problem: Null Pointers
Looking at your main function, you've declared these variables as pointers initialized to 0 (which is the same as NULL in C):
int *dealerTotal = 0; int *playerTotal = 0; int *ranOut = 0;
When you pass these to playHand and try to do something like *ranOut = TRUE, you're trying to write to memory that doesn't exist. The pointers aren't pointing to any valid integer variable—they're just null. That's exactly what causes the Read Access Violation crash.
Fix 1: Use Regular Integers + Pass Their Addresses
You don't need to declare these as pointers in main at all. Instead, use normal integer variables, and pass their memory addresses to playHand so the function can modify their values. Here's how to adjust main:
int main() { // ... (keep your file opening code the same) int dealerTotal = 0; // Regular int, initialized to 0 int playerTotal = 0; int ranOut = 0; while (1) { playHand(&dealerTotal, &playerTotal, &ranOut); // Pass addresses with & if (ranOut == TRUE) break; // No need to dereference here anymore } printf("Total Dealer Wins: %d\n", dealerTotal); printf("Total Player Wins: %d\n", playerTotal); // ... (keep the rest of main the same) }
Fix 2: Fix Operator Precedence in playHand
In your playHand function, lines like *dealerTotal++; have a bug due to operator precedence. The ++ operator runs before the dereference *, so this is actually moving the pointer forward instead of incrementing the value it points to. Wrap the dereference in parentheses to fix this:
if (dWin) { (*dealerTotal)++; // Increment the value at the pointer break; } else if (pWin) { (*playerTotal)++; break; }
Fix 3: Logic Error in Ace Handling
Your getCard function has a flawed condition for Ace values:
case 'A': if(total > 10) y = 1; else if (total >= 10) y = 11; break;
The else if (total >=10) will never run because total >10 already covers all cases where total is 11 or higher. Rewrite this to correctly handle Ace values:
case 'A': // If adding 11 would push total over 21, use 1; else use 11 y = (total >= 10) ? 1 : 11; break;
Fix 4: Simplify Sum Calculations (Optional but Cleaner)
Instead of recalculating sumP and sumD by adding all 10 array elements every loop, track the sum incrementally as you add new cards. This is more efficient and less error-prone:
int sumP = 0; int sumD = 0; // When getting a new player card: pCard[i] = getCard(sumP); sumP += pCard[i]; // Same for dealer: dCard[i] = getCard(sumD); sumD += dCard[i];
Modified playHand Example
Here's how the function might look with all fixes applied:
int playHand(int *dealerTotal,int *playerTotal, int *ranOut) { int pCard[10] = { 0 }; int dCard[10] = { 0 }; int dWin = 0; int pWin = 0; int i = 0; int dFin = 0; int pFin = 0; int sumP = 0; int sumD = 0; *ranOut = FALSE; // Reset ranOut at the start of each hand while (i < 10) { // Player's turn if (sumP <= 15) { pCard[i] = getCard(sumP); if (pCard[i] == 42) { *ranOut = TRUE; break; } sumP += pCard[i]; } else { pFin = TRUE; } // Dealer's turn if (sumD <= 16) { dCard[i] = getCard(sumD); if (dCard[i] == 42) { *ranOut = TRUE; break; } sumD += dCard[i]; } else { dFin = TRUE; } // Check win conditions if (sumP > 21 || sumD == 21) { dWin = TRUE; pWin = FALSE; } else if (sumD > 21 || sumP == 21) { dWin = FALSE; pWin = TRUE; } else if (dFin && pFin) { dWin = (21 - sumP) > (21 - sumD); pWin = !dWin; } if (dWin || pWin) { if (dWin) (*dealerTotal)++; if (pWin) (*playerTotal)++; break; } i++; } return 1; }
Final Notes
Pointers can feel overwhelming at first—just remember: a pointer is a variable that holds a memory address. If you declare a pointer without pointing it to a valid piece of memory (like an existing int), trying to dereference it will always cause a crash. Using & to pass the address of a regular variable is a safe way to let functions modify variables outside their scope. Keep practicing, you've got this!
内容的提问来源于stack exchange,提问作者Alex H.

