为某些数据分配内存有什么好处。相反,我们可以使用它们的数组。
像
int *lis;
lis = (int*) malloc ( sizeof( int ) * n );
/* Initialize LIS values for all indexes */
for ( i = 0; i < n; i++ )
lis[i] = 1;
我们可以使用普通数组。
嗯,我不明白malloc是如何工作的,实际上是做什么的。所以解释它们对我来说会更有益。
假设我们在上面的代码中只用sizeof(int) * n
替换n
,然后尝试存储整数值,我可能面临哪些问题?有没有办法直接从内存分配空间打印存储在变量中的值,例如这里是lis
?
答案 0 :(得分:6)
您的问题似乎是将动态分配的C风格数组与可变长度数组进行比较,这意味着这可能是您正在寻找的内容:Why aren't variable-length arrays part of the C++ standard?
然而,c++代码会产生最终答案: 使用std::vector
对象。
只要有可能,就避免动态分配和对丑陋的内存管理负责〜&gt;尝试利用具有自动存储持续时间的对象。另一个有趣的读物可能是:Understanding the meaning of the term and the concept - RAII (Resource Acquisition is Initialization)
“并假设我们在上面的代码中只用sizeof(int) * n
替换n
,然后尝试存储整数值,我可能面临哪些问题?”
- 如果您仍然认为n
是可以存储在此数组中的整数数量,您很可能会遇到 未定义的行为 。
答案 1 :(得分:3)
更基本的是,我认为,除了堆栈与堆和变量与常量问题(除了你不应该在C ++中使用malloc()
这一事实之外),是一个函数退出时,本地数组不再存在。如果你返回一个指向它的指针,那么一旦调用者收到该指针就会没用,而用malloc()
或new
动态分配的内存仍然有效。例如,您无法使用本地数组实现类似strdup()
的函数,或者合理地实现链接的表示列表或树。
答案 2 :(得分:2)
答案很简单。本地 1 数组在您的堆栈上分配,这是一个为您的程序预先分配的小内存。除了几千个数据之外,你在堆栈上真的做不了多少。对于更大量的数据,您需要从堆栈中分配内存。
这是malloc
的作用。
malloc
分配一块与你问的一样大的内存。它返回一个指向该内存开头的指针,该指针可以被视为类似于数组。如果写入超出该内存的大小,则结果为未定义的行为。这意味着一切都可以正常工作,或者您的计算机可能会爆炸。最有可能的是,您会遇到分段错误错误。
从内存中读取值(例如用于打印)与从数组中读取相同。例如printf("%d", list[5]);
。
在C99之前(我知道问题标记为C ++,但可能你正在学习C-C ++编译),还有另一个原因。你无法在堆栈上拥有一个可变长度数组。 (即使是现在,堆栈上的可变长度数组也不是那么有用,因为堆栈很小)。这就是为什么对于可变数量的内存,您需要malloc
函数来根据需要分配大小的内存,其大小在运行时确定。
本地数组或任何局部变量之间的另一个重要区别是对象的生命周期。一旦范围完成,局部变量就无法访问。 malloc
个对象会一直存在,直到它们为free
d。这在几乎所有非数组的数据结构中都是必不可少的,例如链表,二叉搜索树(和变体),(大多数)堆等。
malloc
ed对象的示例是FILE
。调用fopen
后,保存与打开文件相关的数据的结构将使用malloc
动态分配,并作为指针返回(FILE *
)。
1 注意:非本地数组(全局或静态)在执行之前被分配,因此它们实际上不能在运行时确定长度。
答案 3 :(得分:1)
我假设您在询问c maloc()
的目的是什么:
假设您想从用户那里获取输入,现在分配一个这样大小的数组:
int n;
scanf("%d",&n);
int arr[n];
这将失败,因为n在编译时不可用。来malloc()
你可以写:
int n;
scanf("%d",&n);
int* arr = malloc(sizeof(int)*n);
实际上malloc()
在堆区域中动态分配内存
答案 4 :(得分:0)
某些较旧的编程环境根本没有提供malloc
或任何等效功能。如果你需要动态内存分配,你必须在巨大的静态数组之上自己编写代码。这有几个缺点:
所以现在即使是非常准确的嵌入式环境也会为您提供某种动态分配器。
然而, 过度使用动态内存导致效率低下,这种事实通常很难消除,因为它已经融入了体系结构中。如果看起来手头的任务不需要动态分配,也许它不会。
然而,不使用动态内存分配时,你真的应该会导致它自己的问题,例如对字符串的长度施加硬性上限,或者对API进行非正规性处理(比较gethostbyname
至getaddrinfo
)。
所以你必须仔细考虑。
答案 5 :(得分:0)
我们可以使用普通数组
在C ++中(至少今年),数组具有静态大小;所以从运行时值创建一个:
int lis[n];
是不允许的。一些编译器允许将其作为非标准扩展,并且它将于明年成为标准;但是,就目前而言,如果我们想要一个动态大小的数组,我们必须动态分配它。
在C中,这意味着要弄乱malloc
;但你问的是C ++,所以你想要
std::vector<int> lis(n, 1);
分配一个大小为n
的数组,其中int
值初始化为1。
(如果您愿意,可以使用new int[n]
分配数组,并在完成时记得用delete [] lis
释放它,并且如果抛出异常,请特别注意不要泄漏;但生活对于那些废话来说太短了。)
C中的嗯,我不明白malloc是如何工作的,实际上是做什么的。所以解释它们对我来说会更有益。
malloc
和C ++中的new
从“免费商店”分配持久性内存。与变量超出范围时自动释放的局部变量的内存不同,这将持续存在,直到您明确释放它(C中的free
,C ++中的delete
)。如果您需要数组超过当前函数调用,则必须执行此操作。如果数组非常大,这也是一个好主意:局部变量(通常)存储在堆栈上,大小有限。如果溢出,程序将崩溃或出错。 (并且,在当前的标准C ++中,如果大小不是编译时常量,则必须这样做。)
假设我们在上面的代码中只用
sizeof(int) * n
替换n
然后尝试存储整数值,我可能面临哪些问题?
您没有为n
整数分配足够的空间;所以假设你的代码将尝试访问超出分配空间末尾的内存。这将导致未定义的行为;如果你很幸运会崩溃,如果你不走运就会导致数据损坏。
有没有办法直接从内存分配空间打印存储在变量中的值,例如这里是
lis
?
你的意思是这样的吗?
for (i = 0; i < len; ++i) std::cout << lis[i] << '\n';