关于C语言中数组的动态内存分配

关于C语言中数组的动态内存分配,c,algorithm,memory,merge,C,Algorithm,Memory,Merge,我想要实现的是通过比较每个数组中的两个元素来创建一个由两个排序数组组成的合并数组,例如[0,1,2,3,4]+[2,4,6,8,10]=>[0,1,2,2,3,4,4,8,10] 我试图将这种算法应用于动态分配的数组,并将指针参数抛出到定制的merge()函数。请参阅以下摘录 int* merge(int*, int*); int main(int argc, const char * argv[]) { int* arrayA; int* arrayB; i

我想要实现的是通过比较每个数组中的两个元素来创建一个由两个排序数组组成的合并数组,例如[0,1,2,3,4]+[2,4,6,8,10]=>[0,1,2,2,3,4,4,8,10]

我试图将这种算法应用于动态分配的数组,并将指针参数抛出到定制的merge()函数。请参阅以下摘录

int* merge(int*, int*);

int main(int argc, const char * argv[]) {
    
    int* arrayA;
    int* arrayB;
    int* mergedArray;
    
    int index;
    
    arrayA = (int*) malloc(sizeof(int) * 5);
    arrayB = (int*) malloc(sizeof(int) * 5);
    
    //filling out the array A with number elements like [0, 1, 2, 3, 4]
    for(index = 0; index < 5; index++){
        *(arrayA + sizeof(int) * index) = index;
        printf("%d", *(arrayA + sizeof(int) * index));
    }
    
    //filling out the array A with number elements like [2, 4, 6, 8, 10]
    for(index = 0; index < 5; index++){
        *(arrayB + sizeof(int) * index) = (index + 1) * 2;
        printf("%d", *(arrayB + sizeof(int) * index));
    }
    
    printf("\n");
    
    mergedArray = (int *) merge(arrayA, arrayB);
    
    for(index = 0; index < 10; index++){
        printf("%d", *(mergedArray + sizeof(int) * index));
    }
    
    return 0;
}

如果你查看结果中的第一行“01234”,我确信[0, 1, 2,3, 4 ]被存储在阿里亚指向的内存中,但是在MelGe()函数中,如果我打印相应的元素,它会显示[0, 1, 2,4 ],在中间留下元素“3”。

不仅程序的最终结果“0122401240”表明我的代码中存在逻辑谬误,我找不到


如果你能看到逻辑错误,请毫不犹豫地指出一个,你能告诉我为什么分配内存中的元素有差异吗?

你的代码非常复杂,你可以简化很多

解决问题的一种方法是使这两个数组相邻,以便可以像处理单个数组一样处理它,如下面的代码所示

#包括
#包括
int mysort(常量无效*a,常量无效*b){
返回(*(int*)a-*(int*)b);
}
int main(){
int sz1=5,sz2=5;
int*arr1=malloc((sz1+sz2)*sizeof(int));//为两个数组分配
int*arr2=&arr1[sz1];//转到第二个数组
my_fill(arr1);//根据需要设置数组
my_fill(arr2);
qsort(arr1,sz1+sz2,sizeof(int),mysort);//使用标准qsort对两个数组进行排序。
}

显然,如果您想使用自定义排序算法(如合并排序),这是可能的。您可以用自定义算法替换
qsort

您的代码应该受益于输入数组已经排序的事实。只需获取最小值并将其复制到输出数组。对于每个输入数组,维护一个索引,告诉您下一个未使用元素的位置

比如:


为什么要编写像
*(arrayA+sizeof(int)*index)
这样令人困惑的代码,而不是更清晰的
arrayA[index]
?不管怎样,它看起来是错误的,因为它正在做指针运算,需要是
*(arrayA+index)
还没有看完所有的代码,但是
*(arrayA+sizeof(int)*index)=index不正确。C中的指针算法考虑了指向对象的大小,因此
*(arrayA+index)=index会更好。(或者干脆
arrayA[index]=index;
)是的!我想用arrayA[index]代替代码中的一个相当繁琐的算术运算,但它总是返回一个相当奇怪的结果,所以我想,我会坚持我最初的想法。现在我知道“C会考虑指向对象的大小”,也许我应该首先删除所有的sizeof()函数。@kaylum这两个函数是不等价的
*(arrayA+sizeof(int)*index)
相当于
arrayA[sizeof(int)*index]
,而不是
arrayA[index]
。这可能是一个bug,它正在乘以
sizeof(int)
。请记住,指针添加是隐式缩放的,
*(a+b)
相当于
a[b]
。两个版本都按指针目标的大小缩放整数。@TomKarzes是的,这就是为什么我说它看起来是错误的,应该是
*(arrayA+index)
。也许我可以用更好的措辞来评论。这真是太酷了!这是分配内存空间的一种更简单的方法!非常感谢。
//My take on merge() function

int *merge(int *arrayA, int *arrayB) {
  int *mergedArray;
  int i = 0, j = 0, k = 0; // i for arrayA / j for arrayB / k for mergedArray
  int arrayALength;
  int arrayBLength;

  mergedArray = (int *)malloc(sizeof(int) * 10);
  arrayALength = 5;
  arrayBLength = 5;

  while (i < arrayALength && j < arrayBLength) {
    printf("%d / %d\n", *(arrayA + (i) * sizeof(int)), *(arrayB + (j) * sizeof(int)));

    if (*(arrayA + (sizeof(int) * i)) < *(arrayB + (sizeof(int) * j))) {
      *(mergedArray + (k++ * sizeof(int))) = *(arrayA + (i++ * sizeof(int)));
      printf("%d", *(mergedArray + (k - 1) * sizeof(int)));
    } else {
      *(mergedArray + (k++ * sizeof(int))) = *(arrayB + (j++ * sizeof(int)));
      printf("%d", *(mergedArray + (k - 1) * sizeof(int)));
    }
    printf("\n");
  }
  for (; i < arrayALength; i++) {
    *(mergedArray + (k++ * sizeof(int))) = *(arrayA + (i * sizeof(int)));
  }
  for (; j < arrayBLength; j++) {
    *(mergedArray + (k++ * sizeof(int))) = *(arrayB + (j * sizeof(int)));
  }
  return mergedArray;
}
01234
246810
0 / 2
0
1 / 2
1
2 / 2
2
2 / 4
2
4 / 4
4
4 / 0
0
4 / 1
1
4 / 2
2
0122401240Program ended with exit code: 0
#include <stdio.h>
#include <stdlib.h>

int* mergeSortedArraysToSingleSortedArray(int* arrA, size_t szA, int* arrB, size_t szB)
{
    int* res = malloc((szA + szB) * sizeof *arrA);
    if (res == NULL) return NULL;
    
    size_t iA = 0;
    size_t iB = 0;
    size_t i = 0;
    
    // Merge from A and B
    while (iA < szA && iB < szB)
    {
        if (arrA[iA] <= arrB[iB])
        {
            res[i] = arrA[iA];
            ++iA;
        }
        else
        {
            res[i] = arrB[iB];
            ++iB;
        }
        ++i;
    }
    
    // Take rest of A (if any)
    while (iA < szA)
    {
        res[i] = arrA[iA];
        ++iA;
        ++i;
    }

    // Take rest of B (if any)
    while (iB < szB)
    {
        res[i] = arrB[iB];
        ++iB;
        ++i;
    }
    
    return res;
}

int main(void) 
{
    int arrA[] =  {0, 1, 2, 3, 4};
    int arrB[] =  {2, 4, 6, 8, 10};
    size_t szA = sizeof(arrA)/sizeof(*arrA);
    size_t szB = sizeof(arrB)/sizeof(*arrB);
    
    int* arrMerged = mergeSortedArraysToSingleSortedArray(arrA, szA, arrB, szB);
    if (arrMerged)
    {
        for (size_t i = 0; i < szA + szB; ++i)
        {
            printf("%d ", arrMerged[i]);
        }
        printf("\n");
    }

    return 0;
}
0 1 2 2 3 4 4 6 8 10