int staticArrayA[10];
int staticArrayB[10];
int *dynamicArrayA = (int *)malloc(sizeof(int) * 10);
int *dynamicArrayB = (int *)malloc(sizeof(int) * 10);
根据我的理解,staticArrayA的值是指向数组中第一个元素的指针,但是表示此基址的指针的行为类似于const指针并且无法更改,在这种情况下,有意义的是你不能设置:
staticArrayA = staticArrayB;
但是动态数组呢?如果它们都只是指向内存中连续字节块的指针,那么为什么不能将它们设置为相等呢?
dynamicArrayA = dynamicArrayB;
看起来dynamicArrayA指向的地址现在与dynamicArrayB指向的地址相同。请给我一些见解。也许我错了,但这就是我想要做的事情:
/* remove any element that is 0 from array. n is size of array */
void compressArray(int *array, int n) {
int size = n;
int index = 0;
int *nuArray = (int *)malloc(sizeof(int) * n);
assert(nuArray != NULL);
for (int i = 0; i < n; i++) {
if (array[i] != 0) {
nuArray[index] = array[i];
index++;
size--;
}
}
nuArray = realloc(nuArray, sizeof(int) * size);
assert(nuArray != NULL);
array = realloc(array, sizeof(int) * size);
assert(array != NULL);
array = nuArray; //This doesn't seem to work
free(nuArray);
}
int main(int argc, const char * argv[]) {
int *array = (int *)malloc(sizeof(int) * 10);
assert(array != NULL);
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
array[i] = 0;
} else {
array[i] = i;
}
}
compressArray(array, 10);
return 0;
}
我确信有更简单,更优雅的方式来编写函数,我知道我可以将nuArray的所有元素复制到数组中,然后使用realloc()来减小大小,但是,我只是希望有人能够对动态数组的本质有所了解,并解释一些这种行为并告诉我为什么赋值不起作用,或者是否存在它的作用。此外,我可以让函数返回一个int *并将array =设置为此函数调用,但是为什么我不能在函数内部执行此操作?感谢您的时间和任何帮助。
答案 0 :(得分:2)
如果它们都只是指向内存中连续字节块的指针,那么为什么不能将它们设置为彼此相等?
当然可以。你只需要了解其后果。
int *dynamicArrayA = (int *)malloc(sizeof(int) * 10);
int *dynamicArrayB = dynamicArrayA;
现在dynamicArrayB
和dynamicArrayA
指向相同的内存。您更改了指向的值,通过其他指针也可以看到更改。
dynamicArrayB[0] = 10; // dynamicArrayA[0] is 10.
dynamicArrayA[5] = 15; // dynamicArrayB[5] is 15.
如果这是你的目标,你可以毫无问题地做到这一点。
更新,以回应OP的评论
该行
array = nuArray; //This doesn't seem to work
在array
中本地更改compressArray
的值。这不会改变array
中main
的值。
您必须采用不同的方法将nuArray
返回main
。
问题的一个解决方案是将compressArray
的返回类型从void
更改为char*
并从函数返回nuArray
。
答案 1 :(得分:1)
int *dynamicArrayA = (int *)malloc(sizeof(int) * 10);
int *dynamicArrayB = (int *)malloc(sizeof(int) * 10);
如果你这样做(哪个可能的话) -
dynamicArrayA = dynamicArrayB; //you want this then don't allocate memory to dynamicArrayA
现在,dynamicArrayA
不会指向malloc
先前为其分配的内存,因此您无法free
该内存块。因此,可能导致内存泄漏。
您可以使用memcpy
执行此任务 -
/* allocate memory to both dynamicArrayA and to dynamicArrayB */
for(int i=0;i<10;i++){
dynamicArrayA[i]=i+1; // store value in dynamicArrayA
}
memcpy(dynamicArrayB,dynamicArrayA,sizeof(int)*10); //copy it to dynamicArrayB
for(int i=0;i<10;i++)
printf("%d",dynamicArrayB[i]); // print values
free(dynamicArrayA);
free(dynamicArrayB);
答案 2 :(得分:0)
让我们来看看compressArray
结束时实际发生的事情:
array = nuArray;
在此声明之后,array
现在指向nuArray
指向的相同内存。 array
之前指向的内存现在可以在compressArray
内访问,但array
中的main
仍然指向原始内存块。这是因为此块的地址是传递给compressArray
的地址,而不是array
变量的地址。
free(nuArray);
这释放了nuArray
指向的内存。但由于array
包含与nuArray
相同的值,即nuArray
指向的内存块的地址,现在array
指向一个释放的内存块,并访问这是未定义的行为。
当函数返回时,main中array
的值不变。这是因为传递了array
的值。
为了使其按预期工作,compressArray
需要获取指针的地址(int **
)并更改指向的内容:
void compressArray(int **array, int n) { // "array" is a pointer to an array
int size = n;
int index = 0;
int *nuArray = (int *)malloc(sizeof(int) * n);
assert(nuArray != NULL);
for (int i = 0; i < n; i++) {
if ((*array)[i] != 0) { // note how we're now accessing the array
nuArray[index] = (*array)[i]; // same here
index++;
size--;
}
}
nuArray = realloc(nuArray, sizeof(int) * size);
assert(nuArray != NULL);
free(*array); // We don't need the memory array pointed to anymore, so free it
*array = nuArray; // This changes "array" in main. Also, don't free nuArray,
// otherwise *array will also point to freed memory
}
然后你这样称呼它:
compressArray(&array, 10);
// print the new contents of array
free(array); // We're done with it now, so free it