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);
}
我正在尝试学习如何创建一个函数,该函数将采用动态 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);
}