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

时间:2015-05-16 11:49:37

标签: c pointers runtime-error realloc

下面的代码合并了2个分别排列的大小为n1和n2的阵列A和B. 合并的输出需要存储在A。

(无需查看整个代码)
怀疑:在重新分配A时,我遇到了运行时错误。为什么呢?

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;
}

编辑: 我在下面给出了更正。 但返回的输出是

-2 1 2 3 5 7 9 11 13 15 
0 3 5 7 9 11 13 15 0 17 

为什么A在从merge()返回之前和刚从main()中的merge()返回后才更改?

2 个答案:

答案 0 :(得分:1)

您在堆栈上分配的阵列上调用realloc()*alloc()函数可以使用

来自man realloc

  

除非ptr为NULL,否则必须通过之前的调用返回   malloc(),calloc()或realloc()。

替换

int A[8];

类似

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

请勿忘记致电free() if you need to

答案 1 :(得分:-1)

这是合并排序的算法:

通知看起来与发布的代码实现的内容完全不同。

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

- 合并排序 -

合并排序基于Divide和conquer方法。它需要对列表进行排序并将其除去

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

排序清单。通过不断调用merge-sort算法对两个未排序的列表进行排序;我们

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

算法:

这是一种分而治之的算法。其工作原理如下 -

  1. 将我们必须排序的输入分成两部分。将其称为左侧部分
  2. 和右边部分。

    示例:输入为-10 32 45 -78 91 1 0 -16然后左边部分为-10 32 45 -

    78,右边部分为91 1 0 6。

    1. 分别对每个进行排序。请注意,这里排序并不意味着使用其他一些
    2. 对其进行排序

      方法。我们递归地使用相同的函数。

      1. 然后合并两个已排序的部分。
      2. 输入数组中的元素总数(number_of_elements)。输入

        array(array [number_of_elements])。然后调用函数MergeSort()来对输入数组进行排序。

        MergeSort()函数对[left,right]范围内的数组进行排序,即从索引左侧到索引右侧

        以下。 Merge()函数合并两个已排序的部分。分类部件将来自[左,中]和

        [mid + 1,right]。合并后输出已排序的数组。

        MergeSort()函数:

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

        数组的中间索引(中间)计算为(左+右)/ 2。检查是否(左

        只有在离开时才需要排序

        通过左侧部分MergeSort(数组,左,中)和右侧再次调用MergeSort()函数

        部分通过MergeSort函数的递归调用作为MergeSort(数组,mid + 1,右)。最后合并

        使用Merge函数的两个数组。

        Merge()函数:

        将数组的最左侧,最中间和最右侧索引合并为

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

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

        (lpos)被初始化为左右索引位置(rpos)被初始化为数组的mid + 1.

        直到lpos&lt; mid和rpos&lt;右

        if(array [lpos]&lt; array [rpos]),即位置lpos处的数组值小于

        的值 位于rpos的

        数组,然后在当前存储数组[lpos](数组左侧索引处的值)

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

        位置索引(lpos)由1. tempArray [pos ++] = array [lpos ++]

        否则,将数组[rpos](数组右侧索引处的值)存储在

        的当前索引位置(pos)

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

        by 1. tempArray [pos ++] = array [rpos ++]

        直到(lpos&lt; = mid),即数组左侧部分的元素被保留

        tempArray [pos ++] = array [lpos ++],存储数组[lpos](数组左侧索引处的值)

        临时数组的当前索引位置(pos)并递增位置索引(pos)

        并左侧位置索引(lpos)为1.

        直到(rpos&lt; = right),即数组右侧的元素保留

        tempArray [pos ++] = array [rpos ++],存储数组[rpos](数组右侧索引处的值)

        临时数组的当前索引位置(pos)并递增位置索引(pos)

        和右位置索引(rpos)乘以1.

        最后将已排序的数组复制回原始数组。

        属性:

        1. 最佳情况 - 当数组已经排序为O(nlogn)。

        2. 最坏情况 - 当数组按逆序O(nlogn)排序时。

        3. 平均情况 - O(nlogn)。

        4. 需要额外的空间,因此空间复杂度为数组的O(n)和链接的O(logn)

        5. 列表。

          这是一个示例代码,来自http://www.thelearningpoint.net/computer-science/arrays-and-sorting-merge-sort--with-c-program-source-code

          #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;
          }