堆栈上的动态内存分配
我最近尝试了这个实验,其中我没有为未知大小的内存需求进行动态内存分配,而是进行了静态分配。当我声明一个数组 a[i]
时,我保留了 i
(数组的大小)变量并依赖于用户提供的输入。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
void function(int );
int main(void)
{
int i;
printf("Enter:");
scanf("%d",&i);
function(i);
printf("i = %d\n",i);
getch();
return 0;
}
void function(int i)
{
char a[i];
char b[4];
strncpy(a,"hello",i);
strcpy(b,"world");
int j = 0;
char *c = a;
for( j = 0; j< 20; j++ )
printf("%c",*c++);
}
我的问题是:
- 这样的操作合法吗?
- 如果不是,为什么编译器不发出任何警告或错误?
- 该内存将分配在哪里:堆栈还是堆?
- 为什么 ANSI C/GCC 允许这样做?
I recently tried this experiment in which instead of going for dynamic memory allocation for memory requirements of unknown size, I did a static allocation. When an array a[i]
was declared by me, I kept i
(size of the array) variable and dependent on the input that the user gives.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
void function(int );
int main(void)
{
int i;
printf("Enter:");
scanf("%d",&i);
function(i);
printf("i = %d\n",i);
getch();
return 0;
}
void function(int i)
{
char a[i];
char b[4];
strncpy(a,"hello",i);
strcpy(b,"world");
int j = 0;
char *c = a;
for( j = 0; j< 20; j++ )
printf("%c",*c++);
}
My questions are:
- Is such an operation legal?
- If no, why does the compiler not issue any warning or error?
- Where will this memory be allocated: Stack or heap?
- Why does ANSI C/GCC allow this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
它称为变长数组。
VLA 在 ANSI C99 中是合法的,并且作为某些 C99 之前的编译器的扩展。 GCC 支持它作为严格的 C99 和非 C99 代码的扩展。它在 C++0x 中也是合法的。
使用 gcc:
MSDOS 中存在“conio.h”表明您可能正在使用 Microsoft Visual C++ 编译器,因此不必担心。 MS 致力于使他们的编译器更符合 C++0x 标准,但没有声明其 C 编译器模式有多标准。您问为什么法语词典中没有西班牙语方言单词。
它是一个自动对象,因此出于效率原因,大多数 C 实现都会将其放入堆栈中。
它对于在运行时创建可变大小的临时数组非常有用,其生命周期不会超出函数调用范围。
It's called a variable length array.
VLAs are legal in ANSI C99 and as an extension to some pre-C99 compilers. GCC supports it both as strict C99 and as an extension to non-C99 code. It's also legal in C++0x.
With gcc:
The presence of 'conio.h' from MSDOS indicates you're probably using a Microsoft Visual C++ compiler, so don't worry about it. MS has worked to make their compiler more conformant to the C++0x standard, but makes no claims about how standard its C compiler mode is. You're asking why Spanish dialect words aren't in the French dictionary.
It is an automatic object, so most C implementations will put in on the stack for efficiency reasons.
It is useful for creating temporary arrays of variable size at runtime whose lifetime doesn't extend beyond the function call.
这是有效的 C99。
请查看此处在另一个 StackOverflow 问题中获取更详细的解释。
This is valid C99.
Look here for a more detailed explanation in another StackOverflow question.
这是合法的,但并非所有编译器都支持它。至少Visual Studio <= 2003 afaik不支持它。
我假设它不是 Ansi C++,请尝试 gcc -ansi -pedantic。
This is legal, but not all compilers support it. At least Visual Studio <= 2003 afaik do not support it.
I would assume it is not Ansi C++, try gcc -ansi -pedantic.
堆栈上的动态内存分配:
有一个库调用 _malloca,它在程序堆栈上动态分配内存(非常类似于堆上的 malloc)
参考:_malloca
Dynamic memory allocation on stack:
There is a library call _malloca which allocates memory dynamically on program stack (very much like malloc does on Heap)
Reference: _malloca
变长数组在 ANSI C (C89) 中是非法的。尝试提高编译器的警告级别,我确信您会收到警告/错误。
Variable length arrays are illegal in ANSI C (C89). Try upping your compiler's warning level and I'm sure you'll get a warning/error.
代码是有效的,但是在使用可变长度数组时需要记住一件事。
这里没有错误检查。如果
i
太大,此代码可能会失败。The code is valid, but there is one thing to keep in mind when using variable length arrays.
There is no error checking here. This code can fail if
i
is too big.