我在merge_Sort()函数下面实现了合并排序。
它正确排序(当我注释掉free()调用时),但是当我尝试释放已排序子数组占用的内存时会出现问题。
/* merge_Sort() to merge array by didive and conquer*/
/* calls merge_v_1() to merge two sorted subarrays*/
/* merge_v_1() takes two sorted subarrays and copies them to new sorted array, and returns the pointer to this new sorted array*/
int *merge_Sort(int *array, int a, int b)
{
if (a==b)
return array;
else
{
int middle = ((a+b)/2);
int *left_Sub_Array, *right_Sub_Array;
int *left_Sub_Array_1, *right_Sub_Array_1;
left_Sub_Array = merge_Sort(array, a, middle);
right_Sub_Array = merge_Sort((array + (middle - a + 1) ), middle + 1 ,b);
left_Sub_Array_1 = left_Sub_Array;
right_Sub_Array_1 = right_Sub_Array;
int *newArray = malloc((b - a + 1) * (sizeof(int)));
if (newArray == NULL)
{
exit (1);
}
merge_v_1(left_Sub_Array_1, (middle - a + 1), right_Sub_Array_1, (b - middle), newArray);
// PROBLEM IS HERE IN BELOW TWO FREE()
free(left_Sub_Array);
free(right_Sub_Array);
return (newArray);
}
}
最初,我认为这是因为,函数merge_v_1()正在更改指针left_Sub_Array
和right_Sub_Array
。所以我想到将left_Sub_Array
和right_Sub_Array
的值复制到left_Sub_Array_1
和right_Sub_Array_1
,并将这些值传递给merge_v_1(),以便left_Sub_Array
和right_Sub_Array
的值user $ ./a.out
*** Error in `./a.out': free(): invalid pointer: 0x0000000002272014 ***
Aborted (core dumped)
user $
不会被更改。但是,stil,我在释放内存时会遇到问题。
以下是示例输出。
{{1}}
看起来我正在尝试释放一个我不应该的记忆,但我无法弄明白它的根本原因。任何帮助表示赞赏。
答案 0 :(得分:2)
你有1个malloc和2个免费的。这总是一个问题。来自维基百科: http://en.wikipedia.org/wiki/C_dynamic_memory_allocation
动态内存分配的不当使用通常会成为错误的根源。这些可能包括安全漏洞或程序崩溃, 最常见的原因是分段错误。
最常见的错误如下:
不检查分配失败。内存分配不是 保证成功,并可能返回一个空指针。如果 这通常不会检查是否实施了成功的分配 由于产生的分段,导致程序崩溃 空指针取消引用上的错误。内存泄漏。没有 使用free释放内存释放不可重用内存, 程序不再使用该程序。这浪费了内存资源 并且当这些资源存在时可能导致分配失败 累。逻辑错误。所有分配都必须遵循相同的规定 模式:使用malloc分配,用于存储数据,解除分配 免费使用。无法遵守此模式,例如内存使用情况 在调用free(悬空指针)之后或者在调用malloc之前 (狂野指针),通常免费拨打两次("双免费")等 导致分段错误并导致程序崩溃。 这些错误可能是暂时的,很难调试 - 例如,释放 操作系统通常不会立即回收内存,因此 悬挂指针可能会持续一段时间并且似乎有效。
我会检查你在newArray周围的逻辑并摆脱第二个免费。
答案 1 :(得分:2)
内存分配很棘手,与性能关键代码混合(如排序)并不好。这是一个未排序数组的示例,其中包含用于临时存储的相应辅助数组。优势是2个mallocs,然后是2个释放。缺点是内存使用量为2倍。
// Code from Algorithms 4th edition - Robert Sedgewick, et al.
int main(void)
{
int somearray[10];
// fill with data
int tmp_space[10];
sort(somearray, tmp_space, 0, 9);
}
void merge(int *a, int *aux, int lo, int mid, int hi)
{
int i = lo, j = mid+1, k;
memcpy(&aux[lo], &a[lo], sizeof *a *((hi - lo) +1));
// copied memory to auxiliary space. Now add back to real
// space in proper order.
for (k = lo; k <= hi; k++) {
if (i > mid)
a[k] = aux[j++];
else if (j > hi)
a[k] = aux[i++];
else if (aux[j] < aux[i])
a[k] = aux[j++];
else
a[k] = aux[i++];
}
}
void sort(int *a, int *aux, int lo, int hi)
{
if (hi <= lo) return;
int mid = lo + ((hi - low)/2);
// recursively break in half, and from the bottom up merge two halves.
sort(a, aux, lo, mid);
sort(a, aux, mid+1, hi);
merge(a, aux, lo, mid, hi);
}