C语言动态数组删除元素实现求助:禁止使用memmove()
Fixing Your
remove_element Function (Without memmove()) Hey there! Let's break down what's going wrong with your current remove_element implementation and fix it up, plus address some critical issues in your main function that'll cause crashes or weird behavior.
First, Let's Spot the Key Problems
- Your
remove_elementdoesn't shift elements: Right now you only resize the array withrealloc, but you never move the elements after the deleted index forward to fill the gap. This leaves the deleted value hanging around (or garbage data if you resize) and breaks the array's order. - Pointer pass-by-value issue: In C, function parameters are passed by value. When you do
tab = tmp;insideremove_element, you're only modifying a local copy of the pointer—not the original pointer inmain. Somainwill still use the old array size and pointer. - Dangling pointer in
main: You callfree(tab);before trying to delete an element. Afterfree,tabbecomes a dangling pointer—using it will cause undefined behavior (crashes, random values, etc.).
Let's Rewrite the remove_element Function
Since you can't use memmove(), we'll manually shift elements with a loop. To update the original pointer and array length in main, we'll pass pointers to those values (pointer-to-pointer for the array, pointer to int for the length).
Here's the corrected function:
void remove_element(int **tab, int idx, int *array_length) { // Shift all elements after the deleted index forward by one for (int i = idx; i < *array_length - 1; i++) { (*tab)[i] = (*tab)[i + 1]; } // Resize the array to be one element smaller int *tmp = realloc(*tab, (*array_length - 1) * sizeof(int)); if (tmp != NULL) { // Always check realloc success to avoid leaks! *tab = tmp; (*array_length)--; // Update the array length in main } else { // Optional: Handle allocation failure (good practice) printf("Realloc failed - array size unchanged\n"); } }
Fix the main Function
We need to adjust the order of operations (don't free before modifying the array) and pass the correct arguments to remove_element:
int main() { int *tab = malloc(24*sizeof(*tab)); int idx = 0; tab[idx++] = 44; tab[idx++] = 82; tab[idx++] = 57; tab[idx++] = 77; printf("Before insert\n"); print_array(tab, idx); idx++; add(7, 0, tab, idx); printf("After insert\n"); print_array(tab, idx); // Delete element at index 3 BEFORE freeing the array! printf("After delete\n"); remove_element(&tab, 3, &idx); print_array(tab, idx); // Free the array once we're completely done using it free(tab); return(0); }
Let's Explain the Changes
- Element shifting: The loop starts at the index we want to delete, copying each element from
i+1toi—this overwrites the deleted value and moves everything else up to fill the gap. - Pointer-to-pointer: By passing
&tab(the address of the array pointer), we can modify the original pointer inmainwhen we resize withrealloc. - Updating length: Passing
&idxletsremove_elementdirectly update the array length inmain, so we don't have to track it manually outside the function. - Fixed execution order: We now delete the element first, then free the array once we're done with all operations on it.
Test the Corrected Code
When you run this, you'll see:
- Before insert: The original 4 elements (
44, 82, 57, 77) - After insert:
7added at index 0, making the array[7, 44, 82, 57, 77] - After delete: The element at index 3 (
57) is removed, leaving[7, 44, 82, 77]
内容的提问来源于stack exchange,提问作者Aza
相关产品推荐
相关产品推荐

