C语言归并排序中malloc引发程序崩溃的调试求助
归并排序中sort_desassemble函数malloc导致程序崩溃的原因分析
我是C语言初学者(正在学习CS50x),尝试编写归并排序算法,但无法排查sort_disassemble函数中malloc导致程序崩溃的原因。注:代码尚未完成,仅用于测试。
#include <time.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #define LEN 8 int validcount = 0; int *singlep[LEN]; typedef struct { int *first; int *second; } SplitP; void sort(int *arr, int ln); SplitP sort_desassemble(int *arr, int len); int sort_reassemble(int *right, int *left, int lenright, int lenleft); int main(void) { int *arr = malloc(sizeof(int) * LEN); // Randomly generate the array srand(time(NULL)); // Seed ONCE before the loop for (int i = 0; i < LEN; i++) { int n = rand() % 11; // Generates 0 to 10 *(arr + i) = n; } // Print the unsorted printf("unsorted: "); // Print the sorted list for (int i = 0; i < LEN; i++) { printf("%i,", *(arr + i)); } printf("\n"); // Sort it sort(arr, LEN); printf("sorted: "); // Print the sorted list for (int i = 0; i < LEN; i++) { printf("%i", *(singlep + i)); } printf("\n"); } void sort(int *arr, int ln) { // Base if (ln == 1) { // Store it in the pointer array of values *(singlep + validcount) = arr; validcount++; return; } // get the two parts SplitP val = sort_desassemble(arr, ln); int firstln = 0, secondln = 0; // First will always be the same firstln = ln / 2; if (ln % 2 == 0) { secondln = ln / 2; } else // ln is odd { secondln = ln % 2 + firstln; } sort(val.first, firstln); sort(val.second, secondln); } // This function will return an array of pointers that point to the desassembled arrays SplitP sort_desassemble(int *arr, int len) { const int HALF = len / 2; int *newarr = malloc(HALF * sizeof(int)); SplitP value; // First part for (int i = 0; i < HALF; i++) { *(newarr + i) = *(arr + i); } int *newarr2 = malloc(HALF * sizeof(int)); // Second part for (int i = HALF; i < len; i++) { *(newarr2 + i) = *(arr + i); } value.first = newarr; value.second = newarr2; return value; } // right and left should point to the start of two arrays int sort_reassemble(int *right, int *left, int lenright, int lenleft) { // I can use arrays but i want practice on malloc int *arr = malloc((lenright + lenleft) * sizeof(int)); int leftindex = 0, rightindex = 0; // I was confusion i and j so i gave them appropriate names. while ((leftindex < lenleft) && (rightindex < lenright)) { if (*(left + leftindex) < *(right + rightindex)) { // i and j design the index of the area we want to put our number *(arr + (leftindex + rightindex)) = *left; leftindex++; } else if (*(right + rightindex) < *(left + leftindex)) { *(arr + (leftindex + rightindex)) = *right; rightindex++; } else // If there are equal { *(arr + (leftindex + rightindex)) = *(right + rightindex); *(arr + (leftindex + rightindex + 1)) = *(left + leftindex); rightindex++; leftindex++; } } return *arr; }
导致崩溃的核心问题
- 数组索引越界:在
sort_desassemble的第二部分循环中,直接用i作为newarr2的索引,但i从HALF开始(比如len=8时i从4开始),而newarr2仅分配了HALF个int的空间,索引范围是0到HALF-1。写入newarr2[i]会直接访问超出malloc分配的内存区域,破坏堆结构,触发程序崩溃。正确的索引写法应为:*(newarr2 + (i - HALF)) = *(arr + i); - malloc空间分配不足:当
len为奇数时,第二部分的长度是len - HALF(比如len=5时,HALF=2,第二部分长度是3),但当前仅分配了HALF * sizeof(int)的空间,空间不足会导致后续写入越界。正确的分配大小应为(len - HALF) * sizeof(int)。
其他潜在问题
main函数打印排序结果时错误:printf("%i", *(singlep + i));中,*(singlep+i)是指针地址,应使用%p打印指针,或用**(singlep+i)打印指针指向的整数值。sort_reassemble函数设计错误:该函数应返回合并后的数组指针(int*类型),但当前返回的是*arr(数组第一个元素的int值),导致malloc的内存泄漏,也无法完成归并的合并步骤。- 归并排序核心步骤缺失:
sort函数仅完成了递归拆分,未调用sort_reassemble进行合并,无法完成排序逻辑。 - 内存泄漏:所有malloc分配的内存均未调用free释放,长期运行会耗尽系统内存。
内容的提问来源于stack exchange,提问作者Crucial Beauty
相关产品推荐
相关产品推荐

