如何更改指针在 C 函数中指向的内容?
How can I change what a pointer points to within a function in C?
我正在尝试编写一个可调整大小的数组,该数组在满时会扩展。所有功能都可以使用,但调整大小功能不行。
int main(void)
{
int arr[4];
int *ptr = arr;
initializeEmptyArray(ptr);
insertAtIndex(ptr, 0, 4);
insertAtIndex(ptr, 0, 3);
insertAtIndex(ptr, 0, 2);
insertAtIndex(ptr, 0, 1);
resizeArray(&ptr);
for (int i = 0; i < capacity; i++)
{
printf("%i", arr[i]);
}
}
这会启动我的数组 [1,2,3,4],然后调用调整大小数组来测试它。
void resizeArray(int **arr)
{
int *newArr = (int *)malloc(capacity * 2 * sizeof(int));
for (int i = 0; i < capacity; i++)
{
newArr[i] = (*arr)[i];
}
for (int i = capacity; i < capacity * 2; i++)
{
newArr[i] = EMPTY;
}
free(*arr);
*arr = newArr;
}
问题是 arr
的值在我打印时并没有变成 [1,2,3,4,-1,-1,-1,-1](-1 代表空的)。如何更改指针以指向这个新数组?
Capacity代表数组支持的元素个数,初始为4
EMPTY 定义为-1,代表数组中的空位。
您无法调整数组的大小。它的大小是固定的。
因此,如果您想要可以调整大小的内容,请执行以下操作:
int arr[4]; --> int* arr = malloc(4 * sizeof *arr);
顺便说一句:
您似乎漏掉了一行:
capacity = 2 * capacity ;
看看"realloc",你的问题听起来很完美
代码的两个主要问题是 arr
在 main()
中分配在堆栈上,然后 free()
它在 resizerArray()
中。这是一个缺陷,我修复了在 main()
中分配 arr
的堆。在您的循环中,您打印 arr[i]
但将 ptr
传递给更新的 resizeArray()
,但 arr
仍指向现在已释放的内存。我通过删除 ptr
变量解决了这个问题:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EMPTY 0
void resizeArray(int **arr, size_t capacity) {
int *newArr = malloc(2 * capacity * sizeof(int));
// for (int i = 0; i < 2 * capacity; i++) {
// newArr[i] = i < capacity ? (*arr)[i] : EMPTY;
// }
memcpy(newArr, *arr, capacity * sizeof(int));
memset(newArr + capacity, EMPTY, capacity * sizeof(int));
free(*arr);
*arr = newArr;
}
int main(void) {
size_t capacity = 4;
int *arr = malloc(capacity * sizeof(int));
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
for (int i = 0; i < capacity; i++) {
printf("before: %d\n", arr[i]);
}
resizeArray(&arr, capacity);
capacity *= 2;
for (int i = 0; i < capacity; i++) {
printf("after: %d\n", arr[i]);
}
}
我注释掉了 resizeArray 中的循环,这样您就可以看到如何做到这一点。代码打印:
before: 1
before: 2
before: 3
before: 4
after: 1
after: 2
after: 3
after: 4
after: 0
after: 0
after: 0
after: 0
resizeArray()
和调用代码都必须知道因子 2
。这不是一个伟大的设计。也许传递新旧容量?或者传入 size_t *capacity
如果你想在 resizeArray()
中硬编码这个因素可以更新?请记住检查 malloc()
的 return 值以确保它没有失败。
有关调整堆分配内存大小的标准方法,请参阅 realloc()
,有关如何获取预初始化内存的信息,请参阅 calloc()
。
您不能调整具有自动存储持续时间的数组的大小。您可以使用已分配存储持续时间的数组来执行此操作。
所以你应该删除main中的数组声明并写
int *ptr = malloc( 4 * sizeof( int ) );
或
int *ptr = malloc( capacity * sizeof( int ) );
您还忘记更改变量的值 capacity
。我想它没有声明为常量变量。
在这种情况下,函数 resizeArray
可以通过以下方式查找示例
int resizeArray( int **arr )
{
int *newArr = realloc( *arr, capacity * 2 * sizeof(int));
int success = newArr != NULL;
if ( success )
{
*arr = newArr;
for (int i = capacity; i < capacity * 2; i++)
{
newArr[i] = EMPTY;
}
capacity *= 2;
}
return success;
}
注意数组的重新分配可能会失败。所以函数应该向调用者发出重新分配是否成功的信号。
此外,将变量 capacity
用作全局变量也不是一个好主意。
你可以写在 main
int capacity = 4;
int *ptr = malloc( capacity * sizeof( int ) );
// ...
并像
一样调用函数
resizeArray( &ptr, &capacity );
在这种情况下,函数将如下所示
int resizeArray( int **arr, int *capacity )
{
int *newArr = realloc( *arr, *capacity * 2 * sizeof(int));
int success = newArr != NULL;
if ( success )
{
*arr = newArr;
for (int i = *capacity; i < *capacity * 2; i++)
{
newArr[i] = EMPTY;
}
*capacity *= 2;
}
return success;
}
我正在尝试编写一个可调整大小的数组,该数组在满时会扩展。所有功能都可以使用,但调整大小功能不行。
int main(void)
{
int arr[4];
int *ptr = arr;
initializeEmptyArray(ptr);
insertAtIndex(ptr, 0, 4);
insertAtIndex(ptr, 0, 3);
insertAtIndex(ptr, 0, 2);
insertAtIndex(ptr, 0, 1);
resizeArray(&ptr);
for (int i = 0; i < capacity; i++)
{
printf("%i", arr[i]);
}
}
这会启动我的数组 [1,2,3,4],然后调用调整大小数组来测试它。
void resizeArray(int **arr)
{
int *newArr = (int *)malloc(capacity * 2 * sizeof(int));
for (int i = 0; i < capacity; i++)
{
newArr[i] = (*arr)[i];
}
for (int i = capacity; i < capacity * 2; i++)
{
newArr[i] = EMPTY;
}
free(*arr);
*arr = newArr;
}
问题是 arr
的值在我打印时并没有变成 [1,2,3,4,-1,-1,-1,-1](-1 代表空的)。如何更改指针以指向这个新数组?
Capacity代表数组支持的元素个数,初始为4 EMPTY 定义为-1,代表数组中的空位。
您无法调整数组的大小。它的大小是固定的。
因此,如果您想要可以调整大小的内容,请执行以下操作:
int arr[4]; --> int* arr = malloc(4 * sizeof *arr);
顺便说一句:
您似乎漏掉了一行:
capacity = 2 * capacity ;
看看"realloc",你的问题听起来很完美
代码的两个主要问题是 arr
在 main()
中分配在堆栈上,然后 free()
它在 resizerArray()
中。这是一个缺陷,我修复了在 main()
中分配 arr
的堆。在您的循环中,您打印 arr[i]
但将 ptr
传递给更新的 resizeArray()
,但 arr
仍指向现在已释放的内存。我通过删除 ptr
变量解决了这个问题:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EMPTY 0
void resizeArray(int **arr, size_t capacity) {
int *newArr = malloc(2 * capacity * sizeof(int));
// for (int i = 0; i < 2 * capacity; i++) {
// newArr[i] = i < capacity ? (*arr)[i] : EMPTY;
// }
memcpy(newArr, *arr, capacity * sizeof(int));
memset(newArr + capacity, EMPTY, capacity * sizeof(int));
free(*arr);
*arr = newArr;
}
int main(void) {
size_t capacity = 4;
int *arr = malloc(capacity * sizeof(int));
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
for (int i = 0; i < capacity; i++) {
printf("before: %d\n", arr[i]);
}
resizeArray(&arr, capacity);
capacity *= 2;
for (int i = 0; i < capacity; i++) {
printf("after: %d\n", arr[i]);
}
}
我注释掉了 resizeArray 中的循环,这样您就可以看到如何做到这一点。代码打印:
before: 1
before: 2
before: 3
before: 4
after: 1
after: 2
after: 3
after: 4
after: 0
after: 0
after: 0
after: 0
resizeArray()
和调用代码都必须知道因子 2
。这不是一个伟大的设计。也许传递新旧容量?或者传入 size_t *capacity
如果你想在 resizeArray()
中硬编码这个因素可以更新?请记住检查 malloc()
的 return 值以确保它没有失败。
有关调整堆分配内存大小的标准方法,请参阅 realloc()
,有关如何获取预初始化内存的信息,请参阅 calloc()
。
您不能调整具有自动存储持续时间的数组的大小。您可以使用已分配存储持续时间的数组来执行此操作。
所以你应该删除main中的数组声明并写
int *ptr = malloc( 4 * sizeof( int ) );
或
int *ptr = malloc( capacity * sizeof( int ) );
您还忘记更改变量的值 capacity
。我想它没有声明为常量变量。
在这种情况下,函数 resizeArray
可以通过以下方式查找示例
int resizeArray( int **arr )
{
int *newArr = realloc( *arr, capacity * 2 * sizeof(int));
int success = newArr != NULL;
if ( success )
{
*arr = newArr;
for (int i = capacity; i < capacity * 2; i++)
{
newArr[i] = EMPTY;
}
capacity *= 2;
}
return success;
}
注意数组的重新分配可能会失败。所以函数应该向调用者发出重新分配是否成功的信号。
此外,将变量 capacity
用作全局变量也不是一个好主意。
你可以写在 main
int capacity = 4;
int *ptr = malloc( capacity * sizeof( int ) );
// ...
并像
一样调用函数resizeArray( &ptr, &capacity );
在这种情况下,函数将如下所示
int resizeArray( int **arr, int *capacity )
{
int *newArr = realloc( *arr, *capacity * 2 * sizeof(int));
int success = newArr != NULL;
if ( success )
{
*arr = newArr;
for (int i = *capacity; i < *capacity * 2; i++)
{
newArr[i] = EMPTY;
}
*capacity *= 2;
}
return success;
}