C 重新分配无效指针运行时错误

C 重新分配无效指针运行时错误,c,pointers,runtime-error,realloc,C,Pointers,Runtime Error,Realloc,下面的代码分别合并大小为n1和n2的2个排序数组A和B。 合并后的输出需要存储在 (无需通读整个代码) 疑问:在重新分配时,我遇到了一个运行时错误。为什么? int* temp = (int*)realloc(A,sizeof(int)*(n1+n2)); if(temp != NULL) A = temp; 参考代码: void putinend(int* num,int m,int n){ int i,j; for(i=m-1,j=m+n-1;i>=0;i--)

下面的代码分别合并大小为n1和n2的2个排序数组A和B。
合并后的输出需要存储在

(无需通读整个代码)
疑问:在重新分配时,我遇到了一个运行时错误。为什么?

int* temp = (int*)realloc(A,sizeof(int)*(n1+n2));
if(temp != NULL) A = temp;
参考代码:

void putinend(int* num,int m,int n){
    int i,j;
    for(i=m-1,j=m+n-1;i>=0;i--)
        num[j--] = num[i]; 
}
void merge(int* A, int n1, int* B, int n2) {
    int* temp = (int*)realloc(A,sizeof(int)*(n1+n2));
    if(temp != NULL) A = temp;
    putinend(A,n1,n2);
    int s1=n2,s2=0,i=0;
    while(s1 < n1+n2 && s2 < n2){
        if(A[s1] <= B[s2]) 
            A[i++] = A[s1++];
        else 
            A[i++] = B[s2++];
    }
    while(s1 < n1+n2)
        A[i++] = A[s1++];
    while(s2 < n2)
        A[i++] = B[s2++];
    printf("\n");
    for(i=0;i<10;i++){
        printf("%d ",A[i]);
    }
}
int main() {
    int *A = (int*)malloc(sizeof(int)*8);
    int *B = (int*)malloc(sizeof(int)*2);
    A[0]=1; A[1]=3; A[2] = 5; A[3] = 7; A[4] = 9; A[5] = 11; A[6] = 13; A[7] = 15;
    B[0]=-2; B[1]=2;
    int i;
    merge(A,8,B,2);
    printf("\n");
    for(i=0;i<10;i++){
        printf("%d ",A[i]);
    }
    return 0;
}
为什么在从main()中的merge()返回之前和从merge()返回之后要进行更改?

堆栈上分配的数组上调用
realloc()
。不过,
*alloc()
函数与堆一起工作

man realloc

除非ptr为NULL,否则它必须是由先前对的调用返回的 malloc()、calloc()或realloc()

替换

int A[8];
有点像

int* A = malloc(8 * sizeof(int));

不要忘记调用
free()

以下是合并排序的算法:

注意,它与发布的代码所实现的完全不同

注意:这是实现合并排序算法的递归方法

--合并排序--

合并排序基于分治方法。它需要对列表进行排序并对其进行分割

对半创建两个未排序的列表。然后对两个未排序的列表进行排序和合并,以获得一个

排序列表。两个未排序的列表通过不断调用合并排序算法进行排序;我们

最终得到大小为1的列表,该列表已排序。然后合并大小为1的两个列表

算法:

这是一个分治算法。其工作原理如下——

将我们必须输入的输入分成中间的两部分。叫它左边的部分 还有右边

示例:假设输入为-103245-789110-16,则左侧部分将为-103245-

78,右边部分为91 1 0 6

  • 分别对它们进行排序。注意,这里的sort并不意味着使用其他方法对其进行排序
  • 方法。我们递归地使用相同的函数

  • 然后合并两个排序的部分
  • 输入数组中的元素总数(元素数)。输入

    数组(数组[元素的数量])。然后调用函数MergeSort()对输入数组进行排序

    函数的作用是:在[left,right]范围内对数组进行排序,即从索引左到索引右

    包括在内。函数的作用是:合并两个已排序的部分。已排序的零件将来自[左、中]和

    [中间+1,右]。合并后输出排序的数组

    MergeSort()函数:

    它将数组、数组最左边和最右边的索引作为参数进行排序

    数组的中间索引(mid)计算为(左+右)/2。检查是否(左) 只有在剩下的时候才需要排序 通过在左边部分MergeSort(数组、左边、中间)和右边再次调用MergeSort()函数

    以MergeSort(数组,mid+1,右)的形式递归调用MergeSort函数

    使用合并函数的两个数组

    Merge()函数:

    它将要合并的数组、最左边、最中间和最右边的索引作为

    需要一个临时数组(tempArray[right-left+1])来存储新排序的部分

    临时数组的当前索引位置(pos)初始化为0。左索引位置

    (LPO)初始化为阵列的左索引位置,右索引位置(RPO)初始化为阵列的mid+1

    直到LPO 如果(数组[lpos]<数组[RPO]),即lpos位置的数组值小于

    阵列位于RPO位置,然后将阵列[LPO](阵列左索引处的值)存储在当前位置

    索引临时数组的位置(pos),并增加位置索引(pos)和左

    位置索引(lpos)乘以1。临时数组[pos++]=数组[lpos++]

    否则,将数组[RPO](数组右索引处的值)存储在的当前索引位置(pos)

    临时数组并递增位置索引(pos)和右位置索引(RPO)

    按1.临时数组[pos++]=数组[RPO++]


    直到(LPO您只能从
    malloc
    (或
    calloc
    )获得的
    realloc
    )或者后续的
    realloc
    调用。@pmg实际上,这不完全正确。如果传递给
    realloc
    的指针为空,则它的功能与
    malloc
    完全相同。对!感谢提醒,@sevenbits当realloc失败时,目标数组中就没有空间添加字符。因此,当realloc f如果出现问题,则函数merge()应:1)返回并显示故障指示,或2)释放任何malloc区域,显示诊断消息(建议使用“peror()”并退出程序。在C中,不要强制转换malloc()和函数族的返回值。始终检查malloc()和函数族的返回值(!=NULL)无论如何,您仍然应该
    释放
    内存;依赖操作系统来释放内存是一种糟糕的编程实践。当然,除非我们讨论的是堆栈分配内存。虽然这肯定是一个长而详细的答案,但除了从不处理
    realloc
    问题之外,我不确定它是否能简洁地回答OP的问题。诚然,其他人已经回答了这一部分,但是用代码发布合并排序的完整描述并不能告诉OP他所做的有什么错。@DavidHoelzer,在最后发布的代码中有太多的卷积和不必要的复杂化,我发现这要容易得多(我怀疑对OP更有用)只发布一个正确的合并排序算法,而不是纠正只在特定条件下有效的发布代码(带有注释)
    int* A = malloc(8 * sizeof(int));
    
    #include<stdio.h>
    /*This is called Forward declaration of function */
    void Merge(int * , int , int , int );
    /* Logic: This is divide and conquer algorithm. This works as follows.
             (1) Divide the input which we have to sort into two parts in the middle. Call it the left part
                  and right part.
                 Example: Say the input is  -10 32 45 -78 91 1 0 -16 then the left part will be
                 -10 32 45 -78 and the right part will be  91 1 0 6.
             (2) Sort Each of them seperately. Note that here sort does not mean to sort it using some other
                  method. We already wrote fucntion to sort it. Use the same.
             (3) Then merge the two sorted parts.
    */
    /*This function Sorts the array in the range [left,right].That is from index left to index right inclusive
     */
    void MergeSort(int *array, int left, int right)
    {
            int mid = (left+right)/2;
            /* We have to sort only when left<right because when left=right it is anyhow sorted*/
            if(left<right)
            {
                    /* Sort the left part */
                    MergeSort(array,left,mid);
                    /* Sort the right part */
                    MergeSort(array,mid+1,right);
                    /* Merge the two sorted parts */
                    Merge(array,left,mid,right);
            }
    }
    /* Merge functions merges the two sorted parts. Sorted parts will be from [left, mid] and [mid+1, right].
     */
    void Merge(int *array, int left, int mid, int right)
    {
            /*We need a Temporary array to store the new sorted part*/
            int tempArray[right-left+1];
            int pos=0,lpos = left,rpos = mid + 1;
            while(lpos <= mid && rpos <= right)
            {
                    if(array[lpos] < array[rpos])
                    {
                            tempArray[pos++] = array[lpos++];
                    }
                    else
                    {
                            tempArray[pos++] = array[rpos++];
                    }
            }
            while(lpos <= mid)  tempArray[pos++] = array[lpos++];
            while(rpos <= right)tempArray[pos++] = array[rpos++];
            int iter;
            /* Copy back the sorted array to the original array */
            for(iter = 0;iter < pos; iter++)
            {
                    array[iter+left] = tempArray[iter];
            }
            return;
    }
    int main()
    {
            int number_of_elements;
            scanf("%d",&number_of_elements);
            int array[number_of_elements];
            int iter;
            for(iter = 0;iter < number_of_elements;iter++)
            {
                    scanf("%d",&array[iter]);
            }
            /* Calling this functions sorts the array */
            MergeSort(array,0,number_of_elements-1);
            for(iter = 0;iter < number_of_elements;iter++)
            {
                    printf("%d ",array[iter]);
            }
            printf("\n");
            return 0;
    }