加载大尺寸矩阵时realloc内存分配失败问题排查
realloc Failure Hey, let's break down why your realloc is returning NULL when handling large matrices—there are several critical issues in the code that are causing memory corruption and incorrect memory management.
Key Issues Causing the Problem
1. Pass-by-Value Bug in multiply (Critical Heap Corruption)
The biggest problem is how you're handling the values pointer in the multiply function. In C, pointers are passed by value, so when you do:
int *temp = realloc(values, (start_left + new_size) * sizeof(int)); if (temp != NULL) values = temp;
You're only updating the local copy of values inside multiply—the original values pointer in main remains pointing to the old (possibly freed) memory. This creates a dangling pointer, and any subsequent operations on values in main will corrupt the heap. Over time, this corruption leads to realloc failing with NULL.
2. Uninitialized temp Pointer in main
In main, you declare int *temp; without initializing it. Later, in error handling code, you call free(temp);—freeing an uninitialized pointer causes undefined behavior, which can also corrupt the heap and break future memory allocations.
3. Incorrect Indexing in sum Function
The sum function assumes matrices are stored consecutively in values as i * r * c, but after multiply operations, the memory layout changes (old matrices are replaced by new ones). This leads to out-of-bounds memory access, further corrupting the heap.
4. Potential size Miscalculations
While the size += n*m logic seems okay at first glance, the dangling pointer from issue #1 means size is often tracking an invalid memory footprint, making realloc request more memory than needed (or accessing already freed memory).
Fixes to Resolve the Issues
Fix 1: Pass values by Reference in multiply
Modify multiply to accept a double pointer so it can update the original pointer in main:
int multiply(int **values, int amount_values, int *matrices, int last_mat) { // ... existing code ... if (start_left + new_size > amount_values) { int *temp = realloc(*values, (start_left + new_size) * sizeof(int)); if (temp != NULL) *values = temp; // Update the original pointer else { free(*values); free(matrices); free(result); return -1; } } // ... existing code ... // Update values access to use the double pointer for (int i = 0; i < new_size; i++) (*values)[i + start_left] = result[i]; // ... existing code ... }
Then call it from main with the address of values:
size = multiply(&values, size, arr_matrices, mat_count);
Fix 2: Initialize temp in main
Always initialize pointers to NULL to avoid freeing uninitialized memory:
int *temp = NULL;
Fix 3: Correct Indexing in sum
Calculate the correct start offset for each matrix in values instead of assuming consecutive, fixed-size blocks:
int sum(int *values, int *matrices, int last_mat, int *result) { int r = matrices[1], c = matrices[2]; int current_offset = 0; for (int i = 0; i < last_mat; i++) { int mat_n = matrices[i * 3 + 1]; int mat_m = matrices[i * 3 + 2]; if (r != mat_n || c != mat_m) return -1; // Mismatched dimensions // Add the current matrix's values to the result for (int j = 0; j < r * c; j++) { result[j] += values[current_offset + j]; } current_offset += mat_n * mat_m; // Move to the next matrix's start } return r * c; }
Fix 4: Clean Up negate Function for Clarity
The current loop in negate uses a confusing reverse index—rewrite it to iterate directly over the target matrix's range:
void negate(int *values, int amount_values, int *matrices, int last_mat) { int mat_size = matrices[last_mat * 3 + 1] * matrices[last_mat * 3 + 2]; int start_idx = amount_values - mat_size; for (int i = start_idx; i < amount_values; i++) { values[i] *= -1; } }
Additional Checks
- Verify the
mat_countlogic inmain: After the loop ends, you have an extramat_count++;which may overcount the number of matrices. Double-check this against your input flow. - Ensure all error paths properly free allocated memory to avoid leaks (you're mostly doing this, but the dangling pointer issue was breaking this).
After applying these fixes, the heap corruption should stop, and realloc should behave as expected even with larger matrices.
内容的提问来源于stack exchange,提问作者Erik Pasztor

