何时在指针上使用数组,反之亦然

时间:2011-04-28 03:10:10

标签: c arrays pointers

我的理解是,除了其他方面,可以使用指针来允许您在需要时动态分配内存(并知道您需要多少内存),而不是预先使用数组静态分配内存。

我很难确定何时更好地节省动态分配的计算时间并选择更大的内存占用而不是占用更大的内存,并使用一些计算时间来仅分配我需要的内存。

有人可以对这个问题有所了解吗?是否有任何可能有用的一般规则?

5 个答案:

答案 0 :(得分:1)

通常,当您知道要处理的数据的总大小或至少是最大数据大小时,您想要使用数组。如果你真的不期望大小的巨大变化,这是特别适用的 - 如果(例如)变化是10到20个项目,那么无论如何都可以最简单地分配20个(除非每个项目都是真的大。)

如果你对提前数据的大小知之甚少,或者(并且很重要的可能性)可能很容易处理太多计划放入堆栈,动态分配变得更加有用。动态分配的主要弱点是,如果您需要知道大小,您需要自己跟踪它,并且由您来确保在完成后释放内存。 C中的许多(尤其是困难的,唠叨的)问题归结为在释放后使用内存,或者在完成内存后忘记释放内存。

答案 1 :(得分:1)

在以下情况下应使用动态分配的内存:

  • 你不知道在编译时你需要多少内存
  • 运行时内存量会有所不同
  • 你需要大量内存

在以下情况下应使用静态分配的内存:

  • 你知道编译时间的大小
  • 所需内存量不足

使用动态分配的内存需要使用系统调用,这是当您编程向操作系统询问某些内容时。您有速度惩罚,因为该过程可能会松开给另一个进程的“处理时间”。操作系统需要做很多事情来完成调用。执行系统调用以询问内存是一个比写入存储在进程堆栈中的数组更重的过程。

答案 2 :(得分:0)

当您的数据是动态的时,您使用动态容器,或者您需要从程序的不同区域传递数据。

1 - 动态数据 假设你有一份邻居名单。他们在你的街道上建造了一所新房子,你必须在列表中添加一个人,但你只为15个邻居分配了足够的空间。此动态内存将允许您增加该容器的大小。这不是真的如何运作。实际上,它找到了一大块必要大小的内存,然后将旧容器复制过来。

或者另一个例子。假设您正在编写一个跟踪地址簿的程序。您的一位用户有十个联系人。另一个用户是公司,有50,000名员工都需要存储在这个地址簿中。您不希望为拥有10个联系人的用户分配50000个空格,因此您可以精确分配所需的空间。

2 - 传递数据 分配静态数据时,它将被放置在堆栈中,然后在超出范围后无法访问。因此,如果调用某个生成数组的函数,然后将数组的内存地址传递回其调用者,则会出现运行时错误。这是因为在退出该函数之后,该数组超出了范围,因此它从堆栈中弹出。

但是,如果你动态地分配它,它会在堆上运行,并且在你释放它或直到程序退出之前不会被释放。因此,你可以只保留指向数组开头的指针,并在整个程序中使用它,而不必担心它超出范围,直到你想要它为止。

答案 3 :(得分:0)

数组只是连续的内存块。声明数组时,指针

int foo[5];

foo(没有索引)是指向该数组中第一个元素的指针。

foo[0] = 1;
*foo = 1;

那些做同样的事情,如:

foo[1] = 2;
*(foo + 1) = 2;

使用int foo[5];创建数组时,您正在堆栈上创建。这是当前函数的本地函数,一旦从函数返回,它就不再有效。如果你malloc()内存,你在堆上创建数组(并有一个指向它的指针)

int *foo = malloc(sizeof(int) * 5);
foo[0] = 1;
*foo = 1;

你必须自己管理这个记忆,并在你完成它时free()

free(foo);

答案 4 :(得分:0)

虽然这个问题有一个公认的答案。让我谈谈一个稍微不同的事情。在C中,有时您可以使用在运行时确定大小的数组。例如:

void foo (int a[], int n) {
    int buf[n];
    /* do something with buf[] */
}

这种数组在堆栈中分配,并且大小可变。与malloc的不同之处在于你没有free()内存;存在函数调用时需要注意的事项。当然这也意味着你可能无法返回数组的地址。