【问题标题】:About the dynamic memory allocation for arrays in C language关于C语言中数组的动态内存分配
【发布时间】:2020-07-07 07:46:14
【问题描述】:

我想要实现的是创建两个排序数组的合并数组,例如 [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;
}

合并函数如下

//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

如果您查看结果中的第一行“01234”,我非常有信心 [0, 1, 2, 3, 4] 存储在 arrayA 指向的内存中,但在合并中() 函数如果我打印相应的元素,它会显示 [0, 1, 2, 4],中间省略元素 '3'。

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

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

【问题讨论】:

  • 你为什么要写像*(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]。乘以sizeof(int) 可能是一个错误。请记住,指针加法隐式缩放,*(a+b) 等价于a[b]。两个版本都按指针目标的大小缩放整数。
  • @TomKarzes 是的,这就是为什么我说它看起来不对,应该是*(arrayA + index)。或许我可以将评论措辞更好一些。

标签: c algorithm memory merge


【解决方案1】:

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

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

#include <stdlib.h>
#include <stdio.h>

int mysort(const void* a, const void* b){
    return (*(int*)a-*(int*)b);
}


int main(){
    int sz1= 5, sz2=5;
    int* arr1 = malloc((sz1+sz2)*sizeof(int)); // Allocate for both arrays
    int* arr2 = &arr1[sz1]; // Go to the 2nd array

    my_fill(arr1); // Setup your arrays as you wish
    my_fill(arr2);

    qsort(arr1, sz1+sz2, sizeof(int), mysort); // Sort both arrays using the standard qsort.

}

显然,如果您想使用自定义排序算法,例如归并排序,这是可能的。您可以将qsort 替换为您的自定义算法。

【讨论】:

  • 这很酷!这是分配内存空间的一种更简单的方法!谢谢!
【解决方案2】:

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

喜欢:

#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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-13
    • 2017-10-02
    • 2021-03-19
    • 2020-02-16
    • 2021-11-12
    • 2010-09-09
    • 2023-03-17
    • 2021-07-17
    相关资源
    最近更新 更多