C 在递归函数中操作全局数组
我正在研究一个算法MOOC,有一个小程序,它以任意顺序获取一个整数数组,计算反转的数量(反转是数组索引的对数C 在递归函数中操作全局数组,c,arrays,pointers,recursion,C,Arrays,Pointers,Recursion,我正在研究一个算法MOOC,有一个小程序,它以任意顺序获取一个整数数组,计算反转的数量(反转是数组索引的对数(I,j),与ia[j]) 下面是我写的代码。我试图用一种“分而治之”的方法来解决这个问题,我们递归地将输入数组分成两半,在计算逆运算时对每一半分别排序,然后合并两半 诀窍是我需要跟踪反转的数量并对数组进行排序,因此我将各种递归调用周围的原始数组作为参数传递给函数,并将反转计数作为返回值传递 代码通过第一组递归调用(依次进行除法和排序[1,5,3])正确执行,但是当我调用mergeAndC
(I,j)
,与ia[j]
)
下面是我写的代码。我试图用一种“分而治之”的方法来解决这个问题,我们递归地将输入数组分成两半,在计算逆运算时对每一半分别排序,然后合并两半
诀窍是我需要跟踪反转的数量并对数组进行排序,因此我将各种递归调用周围的原始数组作为参数传递给函数,并将反转计数作为返回值传递
代码通过第一组递归调用(依次进行除法和排序[1,5,3])正确执行,但是当我调用mergeAndCountSplitInv的第三次调用时,它在以下行崩溃:
sortedArrayLeft = realloc(sortedArrayLeft, sizeof(int)*(rightLen + leftLen));
错误如下:
malloc:**object 0x100103abc错误:未分配realloc'd指针
我看不出哪里没有正确地使用malloc,我已经仔细检查了这个检查,看我是否正确地执行了指针运算,并且不能发现任何错误,但很明显错误是存在的
感谢您的帮助
// main.c
// inversionInC
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// function to help with debugging array/pointer arithmetic
void logArrayLenAndContents (char *arrayName, int arrayToPrint[], int arrayLen){
printf("%s\n", arrayName);
printf("len:%d\n", arrayLen);
for (int idx = 0; idx < arrayLen; idx++) {
printf("array[%d]: %d\n", idx, arrayToPrint[idx]);
}
}
int mergeAndCountSplitInv(int sortedArrayLeft[], int leftLen, int sortedArrayRight[], int rightLen)
{
printf("Calling mergeAndCount with sortedArrayLeft:\n");
logArrayLenAndContents("left Array", sortedArrayLeft, leftLen);
printf("...and sortedArrayRight:\n");
logArrayLenAndContents("right Array", sortedArrayRight, rightLen);
int i = 0;
int j = 0;
int k = 0;
int v = 0; // num of split inversions
int* outArray;
outArray = malloc((leftLen + rightLen) * sizeof(int));
while (i < leftLen && j < rightLen) {
if (sortedArrayLeft[i] < sortedArrayRight[j]) {
outArray[k] = sortedArrayLeft[i];
i++;
} else{
outArray[k] = sortedArrayRight[j];
v += leftLen - i;
j++;
}
k++;
}
// if at the end of either array then append the remaining elements
if (i < leftLen) {
while (i < leftLen) {
outArray[k] = sortedArrayLeft[i];
i++;
k++;
}
}
if (j < rightLen) {
while (j < rightLen) {
outArray[k] = sortedArrayRight[j];
j++;
k++;
}
}
printf("Wrapping up mergeAndCount where outArray contains:\n");
logArrayLenAndContents("outArray", outArray, k);
sortedArrayLeft = realloc(sortedArrayLeft, sizeof(int)*(rightLen + leftLen));
return v;
}
int sortAndCount(int inArray[], int inLen){
printf("Calling sortAndCount with:\n");
logArrayLenAndContents("inArray", inArray, inLen);
if (inLen < 2) {
return 0;
}
int inArrayLenPart1 = ceil(inLen/2.0);
int inArrayLenPart2 = inLen - inArrayLenPart1;
int* rightArray = malloc(sizeof(int) * inArrayLenPart2);
rightArray = &inArray[inArrayLenPart1];
int x = sortAndCount(inArray, inArrayLenPart1);
printf("sortAndCount returned x = %d\n\n", x);
int y = sortAndCount(rightArray, inArrayLenPart2);
printf("sortAndCount returned y = %d\n\n", y);
int z = mergeAndCountSplitInv(inArray, inArrayLenPart1, rightArray, inArrayLenPart2);
printf("mergeAndCount returned z = %d\n", z);
return x+y+z;
}
int main(int argc, const char * argv[])
{
static int* testArray;
testArray = malloc(5 * sizeof(int));
for (int i = 0; i<=4; i++) {
testArray[0] = 1;
testArray[1] = 5;
testArray[2] = 3;
testArray[3] = 2;
testArray[4] = 4;
}
int x = sortAndCount(testArray, 5);
printf("x = %d\n", x);
return 0;
}
//main.c
//反转的
#包括
#包括
#包括
//用于帮助调试数组/指针算法的函数
void LogArrayLendContents(char*arrayName,int-arrayToPrint[],int-arrayLen){
printf(“%s\n”,arrayName);
printf(“len:%d\n”,arrayLen);
for(int-idx=0;idx 对于(int i=0;i这是因为函数返回时,sortedArrayLeft
的值会丢失。重新分配的值不会传递给调用者,因此,sortAndCount
的inaray
可能指向释放的内存,如果realloc
需要重新分配和复制
要解决此问题,请将指针传递给指针,让sortedarray left
传播回sortAndCount的inaray
:
int mergeAndCountSplitInv(int **sortedArrayLeft, int leftLen, int sortedArrayRight[], int rightLen) {
...
*sortedArrayLeft = realloc(*sortedArrayLeft, sizeof(int)*(rightLen + leftLen));
return v;
}
...
int sortAndCount(int **inArray, int inLen) {
...
int z = mergeAndCountSplitInv(inArray, inArrayLenPart1, rightArray, inArrayLenPart2);
}
...
int x = sortAndCount(&testArray, 5);
int*rightary=malloc(sizeof(int)*inaraylenpart2);rightary=&inararay[inaraylenpart1];
:错误。rightary由inaray的一部分重写。它不是malloced地址(不是malloc的返回,所以不能realloc)。注意:这很困难。计数反转的逻辑是正确的(右PARITION值与左中元素的距离)。但您应该知道不需要realloc或局部alloc合并空间。非就地合并排序(实际上就是这样)N个元素不需要超过N个临时空间,一个创造性的参数传递算法和指针算法在开始时只需要一个分配就可以完成这项工作,祝你好运。@WhozCraig顺便说一句,你处理第25行和第26行剩余元素的复制的方法非常聪明。再次感谢你。@Nick不要用它来尝试如果你在C++中做任何事情,除了POD类型。在这种情况下使用<代码> STD:复制< /COD>(尽管如果你只关心反转检测,排序指针数组并保留对象的向量,在这种情况下可能是有保证的)。很高兴你从中得到一些有用的东西。