在c中创建来自未知类型数组的指针数组

时间:2017-06-24 09:55:37

标签: c arrays pointers types

我需要编写一个函数:

未知类型数组,数组大小和元素大小

并返回一个指针数组:首先是负值,然后是正值。这就是我到目前为止所做的事情:

void *mix(void *A, int nElementsA, int sizeOfAnElement) {
    char** res = (char**)malloc(sizeof(char*)*nElementsA*sizeOfAnElement);
    char* p = (char *)A;
    char* bStart = res[0];
    char* bEnd = res[nElementsA*sizeOfAnElement - sizeOfAnElement];
    while (p<(char*)A + nElementsA*sizeOfAnElement) {
        if (*(int*)p>0) {
            bStart = p;
            bStart += sizeOfAnElement;
        }
        else {
            bEnd = p;
            bEnd -= sizeOfAnElement;
        }
        p += sizeOfAnElement;
    }
    return res;
}

我得到满是垃圾的阵列, 我害怕什么?

2 个答案:

答案 0 :(得分:0)

首先:你要做的事情是不可能的,也没什么意义。

你说你有:an unknown type array因此你可以访问数组的任何元素。这样做的:

(*(int*)p

表示您假设元素属于int类型(或兼容)。这显然与未知类型相冲突。

除此之外......

这一行

malloc(sizeof(char*)*nElementsA*sizeOfAnElement);

分配太多内存。它只应为每个元素分配一个指针,即

malloc(sizeof(char*)*nElementsA);

答案 1 :(得分:0)

修正:

void *mix(void *A, int nElementsA, int sizeOfAnElement,
           int (*isPositive)(const void *)) {
    // Allocate a `char*` array containing `nElementsA` pointers.
    char **res = malloc(nElementsA * sizeof *res);

    // &p[i] == &A[i]
    char (*p)[sizeOfAnElement] = A;

    // bStart points to the first result element.
    char **bStart = &res[0];

    // bEnd points to the last result element.
    char **bEnd = &res[nElementsA - 1];

    // Loop through the array,
    // adding &A[i] at the start of the result array if positive,
    // else at the end of the result array.
    for (int i = 0; i < nElementsA; i++) {
        if (isPositive(p[i])) {
            *bStart = p[i];
            bStart++;
        }
        else {
            *bEnd = p[i];
            bEnd--;
        }
    }
    return res;
}

您对需要分配的内容以及如何使用指针的理解是错误的。

如果你想创建一个指针数组,那么你只需要分配nElementsA指针,而不是nElementsA * sizeOfAnElement指针(你需要存储指针,而不是它们所指向的对象的副本) )。

然后您错误地创建并使用了bStartbEnd。如果要遍历int个对象的数组,则需要int*个对象。对于bStartbEnd,您希望移动char*数组,因此需要char**

我添加了一个函数指针参数,因此您可以使用int以外的类型(否则使用void *AsizeOfAnElement代替{{1}如果你需要帮助,这里有很多答案,你可以通过搜索引擎找到教程。

我还冒昧地将int *A更改为指向数组的指针,因此编译器可以为您执行指针运算,而不是自己执行。如果你愿意,你可以改回来。如果你想在循环中使用指针(即你不能使用p),这里有一个循环版本:

i