当前位置:首页 » 编程语言 » 栈上分配c语言
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

栈上分配c语言

发布时间: 2023-02-23 02:31:23

c语言堆和栈,静态区的理解

楼主问这样的问题,需要澄清平台。比如windows下的与linux下的编译器及很多嵌入式C编译器不同。为什么考虑嵌入式C?原因是目前C语言的很大市场在嵌入式领域。windows下,除了某些特殊需要,java,C++,C#已经优势尽显了。

另外,讨论了半天,q在你代码的那里?我怎么没找到??我眼睛都揉红了也没找见呀
只好表述一下原理
VC下:
1. 函数形参和函数内部非静态局部变量都在栈上分配(所以a,b,p本身都在栈上。但p指向的内容在堆上。q在哪里,我找不到)。
栈的分配的方法是:sp-=字数。
sp是堆栈指针。”字数“是说:你分配一个字节的局部变量,编译器也给你一个字的长度的空间。原因是,堆栈是具有字长度的。16位、32位机器下,字长度为16,64位机器下,字长度为32.
而且,windows下,栈是从高地址向低地址增长的。为什么?栈与堆共享空间,并且,堆从低向高长,栈从高向低长,降低溢出风险。

静态区名字本身就说明了他的特性:静止的,不随程序的运行变化。也就是相对的说,堆和栈都是动态的。静态区是编译器在编译时指定长度、链接时定位地址、windows载入器载入时分配内存。
这里的动与静是编译器和链接器的说法,是语言层面。不适用于系统层面。Windows随时可能将任何用户程序程序的全部资源“请出”内存,也可重新载入,此时,什么静都是浮云。

还有返回值。楼主的main不返回值编译器会警告你的。返回值存在什么地方?
答案是寄存器里AX(EAX,DX,EDX等)。

嵌入式系统里可能这些都不适用。比如,某些嵌入式处理器的形参直接使用寄存器(R0~R15,或A、B等)

❷ c语言内存有几种分配方式

基本上C程序的元素存储在内存的时候有3种分配策略:
静态分配
如果一个变量声明为全局变量或者是函数的静态变量,这个变量的存储将使用静态分配方式。静态分配的内存一般会被编译器放在数据段或代码段来存储,具体取决于实现。这样做的前提是,在编译时就必须确定变量的大小。 以IA32的x86平台及gcc编译器为例,全局及静态变量放在数据段的低端;全局及静态常量放在代码段的高端
自动分配
函数的自动局部变量应该随着函数的返回会自动释放(失效),这个要求在一般的体系中都是利用栈(Stack)来满足的。相比于静态分配,这时候,就不必绝对要求这个变量在编译时就必须确定变量的大小,运行时才决定也不迟,但是C89仍然要求在编译时就要确定,而C99放松了这个限制。但无论是C89还是C99,都不允许一个已经分配的自动变量运行时改变大小。
所以说C函数永远不应该返回一个局部变量的地址。
要指出的是,自动分配也属于动态分配,甚至可以用alloca函数来像分配堆(Heap)一样进行分配,而且释放是自动的。
动态分配
还有一种更加特殊的情况,变量的大小在运行时有可能改变,或者虽然单个变量大小不变,变量的数目却有很大弹性,不能静态分配或者自动分配,这时候可以使用堆(Heap)来满足要求。ANSI C定义的堆操作函数是malloc、calloc、realloc和free。
使用堆(Heap)内存将带来额外的开销和风险。

❸ 关于c语言的数组

你提这个问题涉及几个方面
1.静态存储区
2.静态数组(static数组),全局数组,动态数组,局部数组
3.给数组赋初值

下面分别解答
1.静态存储区/BSS段/栈
一个程序一般分为3段:text段,data段,bss段
text段:就是放程序代码的,编译时确定,只读,
data段:存放在编译阶段(而非运行时)就能确定的数据,可读可写
就是通常所说的静态存储区,赋了初值的全局变量和静态变量存放在这个区域,常量也存放在这个区域
bss段:定义而没有赋初值的全局变量和静态变量,放在这个区域
2.数组定义
函数外不加static定义的数组为全局数组
用static定义静态数组(函数内或函数外)
用malloc定义动态数组
函数内不加static关键字的数组,为局部数组
3.数组赋初值
对全局数组,定义并赋初值,则在data段,定义未赋初值,在bss段
静态数组也一样,无论静态数组是在函数内还是函数外,定义并赋初值,则在data段,定义未赋初值,在bss段
动态数组,全是从堆上分配的
局部数组,从函数的栈上分配的,显然存储在栈上,函数结束就释放

重点区分最具有迷惑性的以下两种定义
int func1()
{
char s[200]="hello world!";
}

int func2()
{
static char s[200]="hello world!";
}

func1中,"hello world!"为常量数组,存放在data段
数组s从func1的栈上分配,然后常量数组的值复制到数组s中

func2中,"hello world!"为初值,数组s编译时就确定在data段,
初值为"hello world!"

❹ 求助: C语言局部变量在栈上分配的方式是怎么样的

1 为什么你觉得会覆盖test0的内存呢?
2 一般情况下,栈是从上(高地址)往下增长的,如果你想弄明白栈的分配情况,先学会汇编,
再写个简单的程序,调试查看生成的汇编码,你应该知道怎么看吧,看完就什么都明白了;
3 test0不会在栈上分配5个字节,你认为会分5个字节是不是觉得“1111”这个玩意儿占用5个
字节呢,这里在栈上分配的是char *变量,占4个字节,你可以去了解一下常量的存放问题;
4 局部变量没有你所谓的”依次压进栈“一说,这个词是针对函数参数入栈说的;
5 局部变量在栈上的位置及对齐方式是编译器说了算,一般没人会去关心这些东西,
关心按几个字节对齐问题最多的还是在使用结构体的时候,序列化啊反序列化啊什么的;
6 关于ARM,太久不用了,不敢多说;7 感觉你知道点儿东西,也想去多知道点儿,但从上面看,你基础不扎实,有点儿乱来;

❺ c语言有几种分配内存的方式,有什么区别

一般而言,有两种内存分配的方式。
1、在栈上分配。特点是当变量离开其作用域时,其内存即释放了,例如局部变量、函数参数等都是在栈上分配的。
2、在堆上分配。特点是变量一直存在,例如new运算符分配出来的内存、全局变量和static静态变量都是在堆上分配的。

❻ C语言问题:内存的分配方式有哪几种

1、静态存储区分配

内存分配在程序编译之前完成,且在程序的整个运行期间都存在,例如全局变量、静态变量等。

2、栈上分配

在函数执行时,函数内的局部变量的存储单元在栈上创建,函数执行结束时这些存储单元自动释放。

3、堆上分配

堆分配(又称动态内存分配)。程序在运行时用malloc或者new申请内存,程序员自己用free或者delete释放,动态内存的生存期由我们自己决定。

(6)栈上分配c语言扩展阅读

栈上分配数组

#include<iostream>

usingnamespacestd;

voidmain()

{

int**arr=NULL;//int型二维数组

introws,columns;

cin>>rows;//2

cin>>columns;//3

//请在此处编写代码,根据rows和columns在栈上分配一个数组arr

...你的代码...

//赋值给数组元素

for(introwIndex=0;rowIndex<rows;rowIndex++)

{

for(intcolumnIndex=0;columnIndex<columns;columnIndex++)

{

arr[rowIndex][columnIndex]=columnIndex+(rowIndex+1)*1000+1;

}

}

//打印每个数组元素

for(rowIndex=0;rowIndex<rows;rowIndex++)

{

for(intcolumnIndex=0;columnIndex<columns;columnIndex++)

{

printf("%d",arr[rowIndex][columnIndex]);

}

printf(" ");

}

}

❼ C语言可以实现为一维数组动态分配内存吗

可以。。

例子如下:

# include <stdio.h>

# include <malloc.h>

void main(void)

{

int len,i, *p;

printf("输入要存放元素的个数:");

scanf("%d", &len); //输入长度构造动态一维数组

p = (int *)malloc(sizeof(int)*5);

for(i=0; i<len; ++i)

scanf("%d",(p+i)); // p+i等同于&p[i];

// 将动态一维数组p的长度增加至6,并将第6个元素赋值为100;

realloc(p,sizeof(int)*6);//realloc重新增加或减少一维数组的长度;

p[5] = 99;

printf("输出内容: ");

for(i=0; i<=len; ++i)

printf("%-5d", p[i]); //p[i]等同于*(p+i);

printf(" ");

❽ C语言:栈中内存分配是连续的,堆中内存分配是不连续的,对吗

1、栈中的内存是操作系统自动分配的,可以理解成为时连续的,对中的内存分配是因为我们malloc空间的时候,申请的空间的大小不一样造成了碎片。使用malloc的时候系统内部有一个空闲内存映射表,系统会自动查找空闲内存中的第一个合适大小的空间分配。
2、每一次分配的内存是连续的,但如果用结构体链表来管理分配的内存就可以将每一次分配的内存虚拟的连接起来,但前提是每一次分配的内存还是连续的,只是每个节点所占的内存单元不是连续的。

❾ C语言中全局变量存放在内存空间中那个位置

在 C 语言中,内存分配方式有以下三种形式:

1、从静态存储区域分配
由编译器自动分配和释放,在程序编译的时候就已经分配好内存,这块内存在程序的整个运行期间都存在,直到整个程序运行结束时才被释放,如全局变量与 static 变量。

2、在栈上分配
同样由编译器自动分配和释放,在函数执行时,函数内部的局部变量都可以在栈上创建,函数执行结束时,这些存储单元将则被自动释放。

需要注意的是,栈内存分配运算内置于处理器的指令集中,它的运行效率一般很高,但是分配的内存容量有限。

3、从堆上分配
也称为动态内存分配,由程序员手动完成申请和释放。程序在运行的时,由程序员使用内存分配函数(如 malloc 函数)来申请内存,使用完之后再由程序员自己负责使用内存释放函数(如 free 函数)来释放内存。

需要注意的是,如果在堆上分配了内存空间,就必须及时释放它,否则将会导致运行的程序出现内存泄漏等错误。

在 C 语言中,不同类型变量的存储位置和作用域也有所不同。

全局变量
从静态存储区域分配,其作用域是全局作用域,也就是整个程序的生命周期内都可以使用。如果程序是由多个源文件构成的,那么全局变量只要在一个文件中定义,就可以在其他所有的文件中使用,但必须在其他文件中通过使用extern关键字来声明该全局变量。

全局静态变量
从静态存储区域分配,其生命周期也是与整个程序同在的,从程序开始到结束一直起作用。与全局变量不同的是,全局静态变量作用域只在定义它的一个源文件内,其他源文件不能使用。

局部变量
从栈上分配,其作用域只是在局部函数内,在定义该变量的函数内,只要出了该函数,该局部变量就不再起作用,也即该变量的生命周期和该函数同在。

局部静态变量
从静态存储区域分配,其在第一次初始化后就一直存在直到程序结束。该变量的特点是其作用域只在定义它的函数内可见,出了该函数就不可见了。

❿ c语言堆和栈的区别

内存分配中的堆和栈

在 C 语言中,内存分配方式不外乎有如下三种形式:

  • 从静态存储区域分配:它是由编译器自动分配和释放的,即内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,直到整个程序运行结束时才被释放,如全局变量与 static 变量。

  • 在栈上分配:它同样也是由编译器自动分配和释放的,即在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元将被自动释放。需要注意的是,栈内存分配运算内置于处理器的指令集中,它的运行效率一般很高,但是分配的内存容量有限。

  • 从堆上分配:也被称为动态内存分配,它是由程序员手动完成申请和释放的。即程序在运行的时候由程序员使用内存分配函数(如 malloc 函数)来申请任意多少的内存,使用完之后再由程序员自己负责使用内存释放函数(如 free 函数)来释放内存。也就是说,动态内存的整个生存期是由程序员自己决定的,使用非常灵活。需要注意的是,如果在堆上分配了内存空间,就必须及时释放它,否则将会导致运行的程序出现内存泄漏等错误。

数据结构的堆和栈

在数据结构中,栈是一种可以实现“先进后出”(或者称为“后进先出”)的存储结构。假设给定栈 S=(a0,a1,…,an-1),则称 a0为栈底,an-1为栈顶。进栈则按照 a0,a1,…,an-1的顺序进行进栈;而出栈的顺序则需要反过来,按照“后存放的先取,先存放的后取”的原则进行,则 an-1先退出栈,然后 an-2才能够退出,最后再退出 a0。

在实际编程中,可以通过两种方式来实现:使用数组的形式来实现栈,这种栈也称为静态栈;使用链表的形式来实现栈,这种栈也称为动态栈。

相对于栈的“先进后出”特性,堆则是一种经过排序的树形数据结构,常用来实现优先队列等。假设有一个集合 K={k0,k1,…,kn-1},把它的所有元素按完全二叉树的顺序存放在一个数组中,并且满足:



则称这个集合 K 为最小堆(或者最大堆)。

由此可见,堆是一种特殊的完全二叉树。其中,节点是从左到右填满的,并且最后一层的树叶都在最左边(即如果一个节点没有左儿子,那么它一定没有右儿子);每个节点的值都小于(或者都大于)其子节点的值。