C 中指向动态数组的指针

Pointers to Dynamic Arrays in C

我正在尝试学习如何创建一个函数,该函数将采用动态 int 数组 (int arrayPtr = (int) malloc...) 并将其替换为另一个动态大批。这个新数组不仅具有不同的值,而且可能包含不同数量的元素。

根据我的研究,我了解到我需要向此函数传递对我的数组指针的引用,而不是指针本身 (&arrayPtr)。这意味着函数签名需要有 int **arrayPtr 而不是 int *arrayPtr。

我觉得这对我来说很有意义;我们需要告诉arrayPtr指向内存中不同的位置,所以我们需要arrayPtr的内存地址而不是它的值(原数组的内存地址);

我写了一个小测试程序看看我是否理解,但我无法让它工作。使用调试,我观察到以下内容:在函数内部,(int **arrayPtr) 不代表整个数组,而只是第一个元素。也就是说,如果我做*arrayPtr[0],我可以得到值500,但是*arrayPtr[1]是不可访问的内存。

这是我的测试程序:

#include <stdlib.h>

void replaceArray(int **arrayPtr, unsigned int arrayLength) {

    int i;
    int *tempArrayPtr;

    tempArrayPtr = (int *)malloc(sizeof(int) * arrayLength);

    for (i = 0; i < arrayLength; ++i) {
        tempArrayPtr[i] = *arrayPtr[i] * 2;
    }

    free(arrayPtr);

    arrayPtr = &tempArrayPtr;

    return;
}

int main(int argc, char **argv) {

    int i;
    int arrayLength = 2;
    int *arrayPtr;

    arrayPtr = (int*)malloc(sizeof(int) * arrayLength);
    for (i = 0; i < arrayLength; ++i) {
        arrayPtr[i] = i + 500;
    }

    replaceArray(&arrayPtr, arrayLength);

    exit(EXIT_SUCCESS);
}

该函数应该创建一个新数组,其中原始数组的每个元素的值加倍,并让调用函数中的 arrayPtr 变量引用新数组。但是,正如我所写的那样,当 replaceArray 函数尝试访问 *arrayPtr[1].

时,它会收到 SIGSEGV

我意识到这个小演示程序没有做任何需要我正在测试的行为的事情。只是为了让我通过一个简单的例子来理解这个概念。

由于这是一个微小的、微不足道的程序,我认为我接受的答案将包含此代码的完整工作版本是合理的。

这两行都是错误的:

free(arrayPtr);
arrayPtr = &tempArrayPtr;

第一行将变量的地址传递给free(),而不是实际分配的数组的地址。由于变量在堆栈上而不是 mallocated,free() 将在此处崩溃或中止。你想要做的是 free(*arrayPtr):.

第二行只是将局部变量arrayPtr设置为变量tempArrayPtr的地址。你想要做的是 *arrayPtr = tempArrayPtr;.

您的代码必须进行三处更改:

void replaceArray(int **arrayPtr, unsigned int arrayLength) {

    int i;
    int *tempArrayPtr;

    tempArrayPtr = malloc(sizeof(int) * arrayLength);

    for (i = 0; i < arrayLength; ++i) {
            tempArrayPtr[i] = (*arrayPtr)[i] * 2;//In this if you use the without braces it will acts array of pointers that is pointing to a array. So we have to get the value from that using that braces.
    }
    free(*arrayPtr);//<< here we have to free the memory of arrayPtr not the address of the &arrayPtr.

    *arrayPtr = tempArrayPtr; // Here you have to assign the address to that value of arrayPtr.

    return;
}

There is no need the type cast the return value of malloc.

查看下面的代码和内联注释。

#include <stdlib.h>

void replaceArray(int **arrayPtr, unsigned int arrayLength) {

    int i;
    int *tempArrayPtr;

    tempArrayPtr = malloc(sizeof(int) * arrayLength);  //do not cast

    for (i = 0; i < arrayLength; ++i) {
        tempArrayPtr[i] = (*arrayPtr)[i] * 2;
    }

    free(*arrayPtr);  // free the *arrayPtr, [which is `arrayPtr` from `main`]

    *arrayPtr = tempArrayPtr;   //copy tempArrayPtr and put it into *arrayPtr

    return;
}

int main(int argc, char **argv) {

    int i;
    int arrayLength = 2;
    int *arrayPtr;

    arrayPtr = malloc(sizeof(int) * arrayLength);  // do not cast
    for (i = 0; i < arrayLength; ++i) {
        arrayPtr[i] = i + 500;
    }

    replaceArray(&arrayPtr, arrayLength);

    exit(EXIT_SUCCESS);
}