定制网站对公司有什么好处网站建设的几种形式

当前位置: 首页 > news >正文

定制网站对公司有什么好处,网站建设的几种形式,做一个企业网站价格,58和搜房那个网站做房产好文章目录 一、为什么全局变量没有被初始化二、怎样初始化全局变量三、栈是什么#xff08;1#xff09;栈的结构#xff08;2#xff09;栈溢出(3)如何避免栈溢出#xff1a;估计栈的大小 四、堆是什么1.示例函数2.char *str;和char str的区别3.malloc()和free#xff08… 文章目录 一、为什么全局变量没有被初始化二、怎样初始化全局变量三、栈是什么1栈的结构2栈溢出(3)如何避免栈溢出估计栈的大小 四、堆是什么1.示例函数2.char *str;和char str的区别3.malloc()和free 五、为什么堆栈常常一起称呼堆和栈的区别六、静态变量会入栈吗七、如何去指定堆具体在某一段空间 一、为什么全局变量没有被初始化 #include stdio.h int g_a123; int add_val(volatile int v){volatile int a321;vva;return v; } int main(){static volatile int s_a1;volatile int b;badd_val(s_a);return 0; }这个函数里如上节所讲函数add_val(volatile int v)里的局部变量a被初始化并分配到了栈空间里但是为什么定义的全局变量int g_a123和 static volatile int s_a1;没有指令来初始化呢 二、怎样初始化全局变量 对局部变量而言初始化是分配指定字节的数据空间和指定字节的地址空间局部变量是保存在RAM中的而对于全局变量全局变量在程序的任何地方都可以访问因此它们通常会存储在RAM中。在程序启动时全局变量会被初始化并分配内存空间。但是如果我们在定义全局变量时使用了const关键字或者将全局变量定义为static类型那么这些变量通常会被存储在Flash中而不是RAM中。这是因为const类型的变量通常被认为是常量它们的值不会被修改因此可以存储在Flash中。而static类型的变量是在程序运行期间只初始化一次并在整个程序执行期间都存在的因此也可以存储在Flash中。 对于flash中的全局变量读写时会被copy到RAM中的指定地址去这个地址是由编译器和系统共同决定的。 KEIL中链接器LINKER会设置RAM基地址和FLASH基地址。所以CPU先从flash中读取数据地址把数据复制到R0寄存器中那这个全局变量就被保存到RAM的0x20000000地址处了。 三、栈是什么 根据局部变量和全局变量的学习大概知道了栈的概念 Stack栈是计算机内存中的一种数据结构它遵循“后进先出Last In First OutLIFO”的原则。在栈中数据的添加和移除只能发生在栈顶因此最后添加到栈中的数据将首先被移除。 在计算机中栈通常用于存储临时数据如函数调用时的参数、局部变量和返回地址等。当一个函数被调用时它的参数和局部变量会被分配在栈上当函数返回时这些数据会被从栈中移除。因此栈提供了一种便捷的方式来管理函数调用和返回过程中的数据。 栈通常是由操作系统自动管理的它使用指针来跟踪栈顶位置当需要将数据压入栈中时指针会向下移动当需要弹出栈顶的数据时指针会向上移动。由于栈的大小通常是固定的因此在栈溢出时会导致程序崩溃。因此在编写程序时需要仔细管理栈的大小避免发生栈溢出问题。 1栈的结构 对于ARM架构的cortex-m3内核栈是向下生长的满栈也就是说栈指针sp最初指向的是用户设置的高地址处比如0x20001000处由于向下增长栈顶指针指向的地址是最新的数据所在的地址而栈底指针指向的地址是最早的数据所在的地址。当栈满时栈顶指针会指向栈底指针所在的地址这时再添加数据就会导致栈溢出。 向下生长的栈“栈指针”寄存器的值指向栈顶的地址每次压栈时它的值会减去压入数据的大小这样就向下生长。而弹出栈顶的数据时栈指针的值会增加这样就向上移动。 2栈溢出 向下生成的满栈如果初始化的函数里定义的变量过大使栈指针不断向下当栈满时栈顶指针会指向栈底指针所在的地址这时再添加数据就会导致栈溢出。 当栈溢出时会发生以下后果 程序崩溃当栈溢出时程序会不可避免地崩溃这可能会导致数据丢失或者程序无法继续执行。 数据损坏由于栈溢出会导致数据越界因此栈中的数据可能会被覆盖或者损坏这会导致程序无法正常工作。 安全漏洞栈溢出也可能导致安全漏洞攻击者可以通过向栈中添加恶意数据来控制程序的执行流程从而执行恶意代码。 内存泄漏如果程序中存在栈对象当栈溢出时这些对象可能无法正确地被释放从而导致内存泄漏。 (3)如何避免栈溢出估计栈的大小 目标是寻找“使用局部变量最多”的调用链。这里采用GPT的答案 1.观察函数调用链栈的大小取决于函数调用的深度和每个函数的局部变量大小。因此观察程序中函数的调用链和局部变量的大小可以大致估算栈的大小。 2.估算函数参数和返回值的大小函数的参数和返回值也会占用栈空间。因此估算函数参数和返回值的大小可以帮助估算栈的大小。 3.考虑递归如果程序中存在递归函数需要考虑递归的深度和局部变量的大小以估算栈的大小。 4.考虑异常处理如果程序中使用了异常处理需要考虑异常处理的堆栈大小以估算栈的大小。 5.使用栈溢出检测工具一些编译器和调试工具提供了栈溢出检测功能可以通过这些工具检测程序中可能出现的栈溢出问题从而优化栈的大小。 四、堆是什么 GPT解释 堆Heap是一种动态分配内存的方式它是操作系统为程序运行时分配内存的一块区域用于存储程序运行时需要动态分配的数据。堆内存是由程序员自己管理的程序员可以通过调用操作系统或编程语言提供的堆管理函数如malloc、new等来分配和释放堆内存。堆内存的大小通常是动态的可以根据程序的需要进行扩展和收缩。 堆内存的特点如下 动态分配堆内存可以根据程序的需要动态分配程序员可以根据实际情况分配所需的内存大小。 程序员管理堆内存的管理由程序员自己负责程序员需要手动调用堆管理函数来分配和释放堆内存。 多线程共享堆内存可以被多个线程共享因此需要考虑线程安全的问题。 内存泄漏由于堆内存的管理由程序员自己负责因此存在内存泄漏的风险程序员需要注意及时释放不再使用的堆内存。 内存碎片堆内存的动态分配和释放容易导致内存碎片问题程序员需要采取一些优化措施来避免内存碎片的问题。 堆内存通常用于存储动态数据结构如链表、树等和大量的数据如图像、音频等因为这些数据的大小通常是不确定的需要动态分配内存来存储。 1.示例函数 #include stdio.h #include stdlib.hint heap(){ char *str; str malloc(100); strcpy(str,helloworld); free(str); } 我们知道对一个函数当执行完里面的定义变量语句后这个变量的空间便被释放了。那对于指定的栈顶到栈底还有很大的一块空间当不创建栈时就是一块空闲空间于是便可以利用malloc来指定一块空闲空间这块空闲空间即不会影响栈空间的分配也不会重叠到底部的全局变量上去因此可以来完成一些动态分配内存空间操作。 2.char *str;和char str的区别 char str声明的是一个字符指针变量即str指向的是一个内存地址存储的是指向一个字符数组的指针。也就是说str是一个指针。 而char str声明的是一个字符数组变量即str存储的是一段字符数组的内容。 具体来说**char *str的使用场景通常是在需要动态分配内存空间的情况下例如使用malloc函数分配一个字符串空间并将其地址赋给str然后通过str指针对字符串进行操作 **。而char str通常用于声明固定长度的字符数组例如char str[100]表示声明了一个长度为100的字符数组可以存储最多100个字符。 例如 // 使用 char *str 定义字符串变量 char str (char) malloc(100 * sizeof(char)); // 动态分配内存空间 strcpy(str, Hello, world!); // 复制字符串 printf(%s\n, str); // 输出字符串 free(str); // 释放内存空间// 使用 char str[100] 定义字符串变量 char str[100] Hello, world!; // 直接初始化字符数组 printf(%s\n, str); // 输出字符串 3.malloc()和free malloc 和 free 是 C 语言中的动态内存分配和释放函数。 malloc 函数用于在堆内存中动态分配一块指定大小的内存空间并返回一个指向这个空间的指针。其函数原型如下 void malloc(size_t size);其中size 参数表示需要分配的内存空间大小以字节为单位。malloc 函数返回一个 void 类型的指针指向分配的内存空间的起始地址。如果分配失败则返回空指针 NULL。 free 函数用于释放之前使用 malloc 函数分配的内存空间其函数原型如下 void free(void *ptr);其中ptr 参数表示需要释放的内存空间的指针即指向由 malloc 函数返回的指针。调用 free 函数后该内存空间将被释放并可以被重新分配给其他变量使用。 综上所述堆就是一块空闲内存可以使用malloc或者free函数来管理它。 五、为什么堆栈常常一起称呼堆和栈的区别 堆和栈是计算机内存管理中两种重要的数据结构它们常常一起被提到因为它们都是用来管理内存空间的。 但是我觉得堆和栈是不同的不应该一起叫做堆栈。堆就是堆栈就是栈。 堆和栈的区别 1.分配方式栈空间由系统自动分配和管理而堆空间需要由程序员手动分配和释放。 2.空间大小栈空间的大小是固定的由系统预先设定而堆空间的大小不固定可以动态地分配和释放。 3.分配效率由于栈空间的分配和释放是由系统自动完成的因此分配和释放的效率比堆空间更高。 4.存储方式栈空间采用先进后出Last In First OutLIFO的方式存储数据主要用于存储函数调用时的参数、局部变量以及函数返回地址等信息而堆空间则没有特定的存储方式用于存储动态分配的数据结构如动态数组、链表等。 5.生命周期栈空间的生命周期与函数调用的生命周期相同函数调用结束后栈空间中的数据也会被自动释放而堆空间的生命周期由程序员手动管理需要在不需要使用堆空间时手动释放空间。 六、静态变量会入栈吗 不会。 静态变量在内存中的存储位置是在程序的数据区data segment中而不是在栈中。因此静态变量不会入栈。 程序的数据区是在程序运行时由系统分配的一块内存空间用于存储全局变量、静态变量和常量等数据。数据区的大小是固定的在编译时就已经确定因此静态变量的空间大小也是固定的不会随着函数的调用而动态变化。 相比之下栈是一种动态的内存空间用于存储函数调用时的参数、局部变量和返回地址等信息。栈空间的大小是有限的通常只有几百 KB 到几 MB因此栈中存储的变量的空间大小和数量都有一定的限制。 七、如何去指定堆具体在某一段空间 如果需要将堆空间分配到指定的地址段可以使用指针类型转换和指针运算等技巧实现。 下面是一个示例代码演示如何手动分配一块大小为 10 个整型变量的堆空间并将其分配到指定的地址段 #include stdio.h #include stdlib.hint main() {int *ptr, start_addr;int size 10;// 分配堆空间ptr (int)malloc(size * sizeof(int));// 将堆空间分配到指定的地址段start_addr (int*)0x10000; // 假设指定地址为 0x10000ptr start_addr;// 释放堆空间free(ptr);return 0; }在上面的代码中首先通过 malloc 函数分配了一块大小为 10 个整型变量的堆空间然后将指针 ptr 指向这块堆空间的起始地址。接着通过将指针 ptr 指向指定的地址段实现了将堆空间分配到指定的地址段。通过 free 函数释放了堆空间。