简体   繁体   中英

Pointers to Dynamic Arrays in C

I am trying to learn how to create a function that will take a dynamic int array (int arrayPtr = (int ) malloc...) and replace it with another dynamic array. This new array will not simply be of different values, but potentially a different number of elements.

From my research, I've learned that I need to pass into this function a reference to my array pointer, rather than the pointer itself (&arrayPtr). That means the function signature needs to have int **arrayPtr instead of int *arrayPtr.

I feel like it makes sense to me; We need to tell arrayPtr to point to a different location in memory, so we need the memory address of arrayPtr rather than its value (the memory address of the original array);

I wrote a little test program to see if I understood, but I cannot get it to work. Using debugging, I've observed the following: From within the function, the (int **arrayPtr) doesn't represent the entire array, but just the first element. That is, I can get the value 500 if I do *arrayPtr[0], but *arrayPtr[1] is inaccessible memory.

Here is my test program:

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

The function is supposed create a new array with the value of each element of the original array doubled, and have the arrayPtr variable in the calling function refer to the new array instead. As i have written it, however, it gets SIGSEGV when the replaceArray function tries to access *arrayPtr[1].

I realize that this little demonstration program is not doing anything that requires the behavior that I'm testing. It is just so that I can understand the concept with a simple example.

Since this is a tiny, trivial, program, I feel justified in that the answer that I accept will contain the complete working version of this code.

There have to be three changes in you code:

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.

Both of these lines are wrong:

free(arrayPtr);
arrayPtr = &tempArrayPtr;

The first line passes the address of your variable to free() , rather than the address of the actual allocated array. Since the variable is on the stack rather than mallocated, free() will crash or abort here. What you want to do instead is free(*arrayPtr): .

The second line merely sets the local variable arrayPtr to the address of the variable tempArrayPtr . What you want to do instead is *arrayPtr = tempArrayPtr; .

See the below code and the inline comments.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM