当前位置: 首页 > 知识库问答 >
问题:

C中这些数组声明之间有什么区别?

祁景山
2023-03-14

人们似乎在说malloc在使用数组时有多棒,当你不知道一个数组在编译时有多少元素时,你可以使用它(?)。没有malloc你就不能这么做吗?例如,如果我们知道一个字符串的最大长度为10,那么下面的结果是否足够接近同一事物?。。。除了能够释放内存之外。

char name[sizeof(char)*10]; 

char *name = malloc(sizeof(char)*10); 

共有3个答案

颜志学
2023-03-14

>

char*name=malloc(sizeof(char)*10);第二个是在堆上分配的,应该用free释放。否则它将在您的应用程序生命周期内保留。如果需要,您可以为第二个重新分配内存。

彭华皓
2023-03-14
匿名用户

char name[sizeof(char)*10]; // better to use: char name[10];

在编译时静态分配一个大小为(char)*10个char元素的向量。sizeof运算符是无用的,因为如果您分配类型为T的元素数组,则分配的大小将已经是sizeof(T)*N,您无需进行计算。堆栈已分配,不需要空闲。通常,当您已经知道所需对象的大小(本例中为字符串的长度)时,可以使用字符名[10]。

char *name = malloc(sizeof(char)*10);

在堆中分配10字节的内存。分配在运行时完成,您需要释放结果。

羊舌墨一
2023-03-14

第一种方法在堆栈上创建一个字符数组。数组的长度将是sizeof(char)*10,但由于char是按大小为1的标准定义的,您可以只写char name[10]
如果您想要一个足够大的数组来存储10个int(每个标准定义的大小至少为2个字节,但通常实现为4个字节),那么int my_数组[10]也可以工作。编译器可以计算出需要多少内存,无需编写类似int-foo[10*sizeof(int)]的代码。事实上,后者是不可预测的:根据大小(int),数组将存储至少20个int,但可能足够大,可以存储40个。无论如何,后一个代码段调用一个函数,malloc将尝试分配足够的内存来存储堆上的10个字符。内存未初始化,因此将包含垃圾。

堆上的内存稍慢,需要编写代码的您更加注意:您必须显式地释放它
同样:char保证大小为1,因此char*name=malloc(10) 在这里也可以。然而,当使用堆内存时,我(并非只有我一个人)更喜欢像这样分配内存:some\u ptr=malloc(10*sizeof*some\u ptr) 使用一些ptr,就像说这个指针指向的任何类型的大小的10倍。如果你以后碰巧更改了类型,你不必重构所有的malloc调用。

回答您的问题“没有malloc,您能做什么”的一般经验法则是,除非您必须使用malloc。堆栈内存更快,更容易使用,但数量较少。这个网站是以一个众所周知的问题命名的,当你把太多的东西推到堆栈上时,你会遇到这个问题:它溢出了。

当您运行程序时,系统会分配一块您可以自由使用的内存。这并不多,但对于简单的计算和调用函数来说已经足够了。一旦用完,您将不得不求助于从堆中分配内存。
但在这种情况下,一个10个字符的数组:使用堆栈。

其他需要考虑的事情:

  • 数组是一个连续的内存块
  • 指针不知道/无法告诉您分配的内存块有多大(sizeof(an\u数组)/sizeof(type)sizeof(A\u指针)
  • 数组的声明不需要使用sizeof。编译器为您计算出大小:<代码>

检查此链接以了解数组和指针之间的差异

再看看这个问题的答案。它解释了为什么指针不能给出正在处理的内存块的确切大小,以及为什么数组可以<考虑一个尽可能支持数组的论点

 类似资料:
  • 问题内容: 声明这样的数组之间的真正区别是什么: 和 问题答案: 有所不同,但在该示例中没有区别。 使用更冗长的方法:在参数中确实有一个额外的选择:如果将数字传递给构造函数,则将获得该长度的数组: 为了说明创建数组的不同方法: 另一个区别是,使用时,您可以设置数组的大小,这会影响堆栈的大小。如果您遇到堆栈溢出(Array.push与Array.unshift的性能)(当数组的大小超过堆栈的大小并必

  • 问题内容: public class SomeClass { private HashSet contents = new HashSet (); private Set contents2 = new HashSet (); } 有什么不同?最终它们都是不是吗?第二个对我来说似乎是错误的,但是我看到它经常被使用,接受和工作。 问题答案: 是一个接口,并且是实现该接口的类。 将变量声明为类型意味着

  • 问题内容: 在Go的整个Google App Engine文档中,它们可互换使用库。这是一个例子: 我应该使用哪些库?主要区别是什么? 问题答案: cloud.google.com/go/datastore是Cloud Datastore rest API(可从任何地方使用)的客户端库。 google.golang.org/appengine/datastore是App Engine API的一部

  • 问题内容: 两者的含义使我难以理解。 问题答案: 甲声明引入的标识符和描述了它的类型,无论是类型,对象,或功能。声明是编译器需要接受对该标识符的引用的内容。这些是声明: 甲定义实际实例化/器具该标识符。这是什么样的连接器需要以链接引用这些实体。这些是与上述声明相对应的定义: 可以使用定义代替声明。 可以根据需要多次声明标识符。因此,以下内容在C和C ++中是合法的: 但是,必须定义一次。如果忘记定

  • %1有编译器错误,而%2是合法的。 为什么变量声明的类型必须与我们传递给对象类型的类型匹配(不允许派生类型)?我使用的数组如下所示,这是完全正确的: 有人能告诉我为什么集合必须声明为条件2吗?谢谢

  • 这个问题似乎离题了,因为它缺乏足够的信息来诊断问题 更详细地描述你的问题,或者在问题本身中包含一个最小的例子。 其中Fragment和Intent是构建类,FragmentABC是用户定义的类。 它非常基本,但仍然无法找出合理的差异来证明实例化。想知道这两种说法的区别是什么,请在你提供的答案中描述一下。