【问题标题】:Dynamic memory allocation and passing in function动态内存分配和传入函数
【发布时间】:2018-03-09 17:43:10
【问题描述】:

我分配内存如下。还试图在另一个函数中更新它。

int main() {
  int* ptr = (int*)malloc(sizeof(int)*3);
  ptr[0] = 0;
  ptr[1] = 1;
  ptr[2] = 2;
  modifyArr(&ptr, 2);
}

void modifyArr(int** arr, int arrLen)
{
    printf("Before modified\n");
    printArray(*arr, arrLen);
    for (int i = arrLen;  i >= 0; i--)
    {
        *arr[i] = i; // here is error
    }
    printf("After modified\n");
    printArray(*arr, arrLen);
}

那么我怎样才能在另一个函数中修改这个数组呢?

如果我的数组被固定为:

int arr[] = { 0,1,2 };

如何在另一个函数中更新它?

【问题讨论】:

  • 您要修改数组内容,还是要重新分配数组(以便更改其大小)?您正在将指针传递给指针,这允许您执行后者(更改值 ptr 以指向重新分配的缓冲区)。如果你只是想改变数组内容,传递指针值就足够了。
  • *arr[i] 不会做你想做的事。可能使用(*arr)[i]
  • 您的指针比您需要的多一级。只需调用modifyArr(ptr, 2); 并声明modifyArr(int *arr, int arrLen) 并编写printArray(arr, arrLen)arr[i] = i 等...在这种情况下,您还需要更改printArray 声明/定义。
  • ptr 已经是一个指针了,你不需要做一个指向它的指针,直接传过去就行了。那么你就不用担心运算符的优先级了。

标签: c memory


【解决方案1】:

数组下标运算符[] 的优先级高于指针解引用运算符*。请参阅order of precedence of operators in C。结果是:

*arr[i] = i;

真正的意思:

*(arr[i]) = i;

这意味着您将arr 视为指针数组,而不是指向数组的指针。结果,您最终写错了地方并调用了undefined behavior

你需要在*arr 周围加上括号才能得到你想要的:

(*arr)[i] = i;

但是,由于您只是更新指针指向的内存而不实际修改指针,因此无需传递指针的地址。直接传入即可:

void modifyArr(int* arr, int arrLen)
{
    printf("Before modified\n");
    printArray(arr, arrLen);
    for (int i = arrLen;  i >= 0; i--)
    {
        arr[i] = i;
    }
    printf("After modified\n");
    printArray(arr, arrLen);
}

然后这样称呼它:

modifyArr(ptr, 2);

您可能还想修改printArray 来做同样的事情。

【讨论】:

  • 但是您根本不需要额外的指针级别。只需将arr 设为简单的int *,并将ptr 传递给它,然后使用arr[i]。您不需要更改指针值本身,只需更改它指向的内容即可。
【解决方案2】:

当你记住两件事时,有指针的事情就很简单了——你想得到什么以及如何得到它?

在这里,您要获取已分配的连续元素内存。你怎么得到它?是的,您使用[]* 是对的,但是还有一件事被称为优先级。 [] 的优先级高于 *。所以你写了这个*(arr[i]),你想要(*arr)[i]。先获取指针,然后在上面使用[]获取元素。

在这里,您实现了所谓的undefined behavior。因为你访问了一些不是你分配的东西。

【讨论】:

    猜你喜欢
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 2021-09-20
    • 2012-01-13
    • 2013-05-29
    相关资源
    最近更新 更多