-
Xilinx SDK编译的源码内存使用问题 大型数组,动态分配内存程序跑飞现象原因与解决
2014-10-19 10:28:05程序执行的时候是需要堆和栈,动态分配的空间是在堆中,程序中的局部变量等是在栈中,xilinx的SDK会默认的将堆和栈设置为1024个字节,这对我们需要使用比较大的内存来说是比较小的,毕竟我们已经使用了DDRSDRAM,动辄...xilinx的工具很强大,在XPS中生成硬件环境后直接生成BSP,基于BSP可建立C语言和C++工程,这里我们很容易跑一个Hello World程序,但是,有时执行自己的程序,得不到想要的结果,仔细检查代码,可能发现与hello world不同的地方也就是在于使用了一个较大的数组或是使用new 关键字或是malloc关键字分配了一个较大的内存,但明明在配置硬件时使用的DDR SDRAM,程序应该在SDRAM上执行才对,而DDR一般容量很大,不可能出现这个问题,仔细分析发现SDK在链接代码时使用了一个lscript.ld
程序执行的时候是需要堆和栈,动态分配的空间是在堆中,程序中的局部变量等是在栈中,xilinx的SDK会默认的将堆和栈设置为1024个字节,这对我们需要使用比较大的内存来说是比较小的,毕竟我们已经使用了DDRSDRAM,动辄几百兆,故我们只需要根据自己需要将堆栈调大点即可
-
动态分配内存
2021-01-28 15:32:14动态分配内存 C++内存分配有两种方式:静态分配和动态分配 静态分配 指在编译时为程序中的数据对象分配相应的存储空间,C语言风格中常见的变量,数组,指针定义等均是静态分配方式。 由于是在编译时为程序中的数据...动态分配内存
C++内存分配有两种方式:静态分配和动态分配
静态分配 指在编译时为程序中的数据对象分配相应的存储空间,C语言风格中常见的变量,数组,指针定义等均是静态分配方式。
由于是在编译时为程序中的数据分配相应的存储空间,因此就要求在编译时空间大小必须是明确的,所以数组的长度必须是常量。而编译一旦完成,运行期间这个数组的长度就固定不变。动态分配 是程序运行期间根据实际需要动态地申请或者释放内存的方式,它不像数组等静态内存分配方式那样需要预先分配存储空间,而是根据程序的需要适时分配,且分配的大小就是程序要求的大小。
因此,动态分配方式有如下特点:
- 不需要预先分配存储空间
- 分配的空间可以根据程序的需要扩大或缩小
new与delete运算
int *p1,*p2; char *str1,*str2; p1 = new int; //分配一个整型空间,若成功,则p1指向该空间,否则p1为NULL p2 = new int(10); //分配一个整型空间,且给这个整型赋初值10,即*p2为10 str1 = new char[100]; //分配一个字符数组(字符串)空间,即str1为字符串指针 str2 = new char[10][100]; //分配一个二维字符数组(字符串数组)空间,即str2为字符串数组指针 delete p1; //释放指向p1指向的整型空间 delete []str1; //释放str1指向的字符串空间
总结:
-
new运算结果是指向分配得到的内存空间的指针,如果没有足够的内存空间可以分配,其运算结果是一个0值指针
-
销毁对象后,指针p1变成没有定义,然而它仍然存放先前所指向的对象(已销毁)的地址,因此,指针p1不再有效,称这样的指针为迷途指针。通常在delete运算之后将指针重设为0值指针,避免迷途指针
-
用new创建的动态对象使用结束后,必须用delete销毁它
-
delete只能删除由new创建的动态对象,否则将导致程序错误
动态内存的应用
-
静态内存管理由编译器进行,程序员只做对象定义(相当于分配),而动态内存管理按程序员人为的指令进行
-
动态内存分配和释放必须对应,即有分配就必须有释放,不释放内存会产生“内存泄漏”,后果是随着程序运行多次,可以使用的内存空间越来越少;另一方面,再次释放已经释放的内存空间,会导致程序出现崩溃性错误
-
静态分配内存的生命期由编译器自动确定,要么是程序运行执行期,要么是函数执行期。动态分配内存的生命期由程序员决定,即从分配时开始,至释放时结束。特别地,动态分配内存的生命期允许跨过多个函数
-
静态分配内存的对象有初始化,动态分配内存一般需要人为的指令赋初值
-
避免释放内存后出现“迷途指针”,应及时设置为空指针
动态内存举例:
#include<iostream> using namespace std; int *f1(int n) { //分配n个整型内存,返回首地址 int *p; p = new int[n]; //分配 for(int i=0;i<n;i++) p[i] = i; //赋初始值 return p; //动态分配的指针返回是有意义的 } void f2(int *p,int n) { //输出动态内存中的n个数据 while(n--) cout<<*p++<<" "; } void f3(int *p) { delete []p; //释放内存 } int main() { int *pi; int n; cin>>n; pi = f1(n); //分配 f2(pi,n); //输出 f3(pi); //释放 return 0; }
动态分配数组和字符串
使用动态内存,可以轻而易举地解决这样的问题:在程序运行时产生任意大小的"数组"
动态分配一维或多维数组的方法是由指针管理数组,二维以上数组按一维数组方式来处理,具体步骤:
- 定义指针p
- 分配数组空间,用来存储数组元素,空间大小按元素个数计算
- 按一维数组方式使用这个数组(例如输入,输出等)
注:若是一维数组,则元素为p[i];若是二维数组,则元素为p[i*m+j],其中m为列元素个数,以此类推 - 释放数组空间
例:计算N*N二维数组的元素平均值
#include<iostream> using namespace std; double AVE(double *A,int N) { //计算N*N二维数组元素的平均值 int sum=0; for(int i=0;i<N;i++) for(int j=0;j<N;j++) sum = sum + *(A+i*N+j); return sum/(N*N); } int main() { int n; cin>>n; double *A = new double[n*n]; //分配数组A[n][n] for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>*(A+i*n+j); //输入数据到A[i][j] cout<<"det A="<<AVE(A,n)<<endl; delete []A; //释放数组 return 0; }
动态分配字符串
实际编程中,字符串类型表示文字信息数据,其特点是字符长度不固定。通过动态分配字符串,根据程序的需要确定字符串的实际长度。
动态分配字符串的方法是由字符指针管理字符串,具体步骤为:
- 定义字符指针
- 分配字符串空间,用来存储字符串
- 使用这个字符串(例如输入输出等)
- 释放字符串空间
char *p = new char[1005]; //分配字符串空间 cin >> p; //输入字符串 cout << p; //输出字符串 delete []p; //释放字符串空间
-
为什么要动态分配内存?什么时候需要动态分配内存?
2019-10-16 21:08:42问:为什么要动态分配内存 答1:因为内存太宝贵。 答2:如果全部是静止内存不能释放,对于小的程序可以运行完毕。但是对于大的程序,还没运行完,内存就要被占用完,此时就要发生内存泄露。 答3:给定一个占用...问:为什么要动态分配内存
答1:因为内存太宝贵。
答2:如果全部是静止内存不能释放,对于小的程序可以运行完毕。但是对于大的程序,还没运行完,内存就要被占用完,此时就要发生内存泄露。
答3:给定一个占用内存可变大小的变量(假设是数组的长度len),给该变量通过函数动态分配内存后,分配内存的大小是根据数组的长度len决定的,假定用户输入len的大小是5,系统就会动态的给该数组分配长度为5的内存,该段代码运行结束后,系统调用free()函数释放分配的内存,然后接着运行剩下的程序。换句话说,动态分配内存可以根据需要去申请内存,用完后就还回去,让需要的程序用。
问:什么时候需要动态分配内存
答:当程序中有比较大的数据块需要使用内存的时候使用。原因:比较大的数据块如果使用了静态内存,在该数据块运行完毕后不能动态的释放该内存,直到整个程序运行完才能释放,如果整个程序比较大,有可能因为内存不够而发生错误。
问:难道不可以在该静态分配的内存使用完后,使用free()函数释放吗?
答:不可以,首先malloc() 函数和free()函数必须是配套使用,其次free()函数不能释放普通变量,只能释放指针。
问:什么时候需要动态分配内存(网友整理:https://blog.csdn.net/sinat_39085247/article/details/74356820)
答:什么时候我们需要动态分配内存空间呢?举一个例子吧。int *p; 我们定义了一个指向int类型的指针p;p是用来储存一个地址的值的,我们之所以要为p这个变量分配空间是让它有一个明确的指向,打个比方吧!你现在做好了一个指向方向的路标,但是你并没有让这个路标指向一个确切的方位,也就是说现在的这个路标是瞎指向的,这样我们就不能够通过它来明确到底哪里是东,哪里是西,何为北,何为南了。虽然我们在计算机的内存里定义了一个指针变量,但是我们并没有让这个变量指示一个确切int类型变量的地址,所以我们就必须要让它有一个明确的指示方向。这样我们就要通过动态分配内存的方式来认为的规定它的方向!
计算机内存的四大区域:栈区,常量区,全局区,堆区(动态分配)
- 栈 区:在栈里面储存一些我们定义的局部变量以及形参;
- 常量区:主要是储存一些字符常量;
- 全局区:在全局区里储存一些全局变量和静态变量;
- 堆 :堆主要是通过动态分配的储存空间;
以数组为例子来说明动态分配和释放内存
#include<stdio.h> #include<malloc.h> int main() { int len;//定义数组的长度 int *pArr=(int *)malloc(sizeof(int)*len); for(int i=0;i<len;++i) scanf("%d"\n,&pArr[i]); for(i=0;i<len;++i) printf("%d\n",*(pArr+i)); free(pArr); //pArr指向数组的首地址 pArr = NULL; /*... 剩余代码 ...*/ return 0; }
问:为什么malloc函数前面需要int *的强制转换?
答:因为程序需要告诉编译器malloc函数返回值的第一个字节是int *类型的还是其他类型的。
1:代码中的malloch函数分配内存,在该段代码运行完后,通过free()函数释放,被释放的内存空间留着可以被剩余代码接着利用。
2:同时当我们使用malloc()函数的时候还应该注意当我们释放完空间的时候还要将原先的指针变量赋予一个NULL,也就是赋予一个空指针,留着下次的时候使用它!如果我们不赋予|NULL行不行呢??答案是:不行的!如果我们不赋予一个空指针这样会导致原先的指针变量成为了一个野指针,何谓野指针?野指针就是一个没有明确指向的指针,系统不知道它会指向什么地方,野指针是很危险的,因此当我们每次使用完malloc()函数的时候都必须将指针赋予一个空指针!
-
C语言-动态分配内存
2020-01-12 19:38:43C语言笔记之动态分配内存1. 动态分配内存是什么?2. 动态分配内存怎么用?2.1 申请动态分配内存`malloc()`2.2 释放动态分配内存`free()`2.3 初始化动态分配内存2.4 重新调整内存大小2.5 内存分配函数小结2.6 标准库...C语言-动态分配内存
1. 动态分配内存是什么?
是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。通常我们的变量都是预先分配的,系统自动给分配和回收的。
2. 动态分配内存怎么用?
C99可以使用变量作为数组定义的大小,在C99之前只能使用动态分配内存实现。
int arr[n];
近似于
int* arr = (int*)malloc(n*sizeof(int)); // 操作arr如同操作int arr[n] free(arr);
2.1 申请动态分配内存
malloc()
stdlib.h
中定义函数void* malloc(size_t size)
,向系统申请大小为size
的内存空间。返回结果是void*
,使用时转换成需要的指针类型。如果申请失败,返回NULL
。
实例:获取系统最大可申请的空间#include <stdio.h> #include <stdlib.h> int main(){ int cnt = 0; while(void* p = malloc(100*1024*1024)) ++cnt; printf("%d00MB\n",cnt); }
2.2 释放动态分配内存
free()
free()
归还申请的内存。#include <stdio.h> #include<stdlib.h> int main() { int n; scanf("%d",&n); int* arr = (int*)malloc(n*sizeof(int)); for(int i=0;i<n;i++){ scanf("%d",arr+i); } for(int i=0;i<n;i++){ printf("%d",arr[i]); } printf("\n"); free(arr); //归还申请的内存。 return 0; }
free()
的注意事项:- 不要忘记
free()
。 - 修改了申请地址,然后
free()
。
int* arr = (int*)malloc(n*sizeof(int)); free(arr+1);
- 多次
free()
。
int* arr = (int*)malloc(n*sizeof(int)); free(arr); free(arr);
free()
非malloc
内存。
int n = 0; free(&n);
- 一般我们需要在
free()
语句的下一条语句增加给指针置空操作,来防止野指针
free(p); p = NULL;
2.3 初始化动态分配内存
calloc()
int* arr = (int*)calloc(n,sizeof(int)); free(arr);
近似于
int arr[n] = {0};
也可以:
int* arr = (int*)malloc(n*sizeof(int)); memset(arr,0,n*sizeof(int)); free(arr);
2.4 重新调整内存大小
realloc()
void* realloc (void* ptr, size_t size);
- 如果当前内存段后面有足够的内存空间,那么就直接扩展这段内存,
realloc()
返回原来的首地址; - 如果当前内存段后面没有足够的内存空间,那么系统会重新向内存树申请一段合适的空间,并将原来空间里的数据块释放掉,而且
realloc()
会返回重新申请的堆空间的首地址; - 如果创建失败,返回
NULL
, 此时原来的指针依然有效;
2.5 内存分配函数小结
No. 函数 作用 1 malloc()
分配内存块,不初始化 2 calloc()
分配内存块,初始化为 0
3 realloc
调整先前分配的内存块大小 4 free
释放分配内存块 2.6 标准库中相关函数
No. 函数 作用 1 memset()
填充内存 2 memcpy()
内存拷贝 3 memmove()
内存移动 4 memcmp()
内存比较 5 memchr()
查找内存中第一个出现指定字符的位置 这些函数通常要加上头文件
stdlib.h
或者string.h
。
练习
从终端输入未知数量的数字,按键Ctrl+D作为结束,逆序输出输入的数字。#include<stdio.h> #include<stdlib.h> int main(){ int num; int* p=NULL; int count =0; while(scanf("%d",&num)!=EOF){ int* t = malloc(count*sizeof(int)); if(NULL!=p){ for(int i=0;i<count;i++){ t[i]=p[i]; } t[count]=num; free(p); p=t; }else{ p=t; p[count]=num; } count++; } for(int i=count-1;i>=0;i--){ printf("%d",p[i]); } printf("\n"); }
简化后为:
#include<stdio.h> #include<stdlib.h> int main(){ int num; int* p=NULL; int count =0; while(scanf("%d",&num)!=EOF){ ++count; p = realloc(p,count*sizeof(int)); p[count-1]=num; } for(int i=count-1;i>=0;i--){ printf("%d",p[i]); } printf("\n");
- 不要忘记
-
内存的静态分配和动态分配的区别【转】 静态分配内存与动态分配内存的区别
2018-10-13 13:52:50内存的静态分配和动态分配的区别【转】 来源: <http://blog.csdn.net/liuchao1986105/article/details/6724392> 内存的静态分配和动态分配的区别主要是两个: 一是时间不同。静态分配发生在... -
c语言动态分配内存及内存分配部分函数
2018-11-08 14:59:50在C中动态分配内存的基本步骤有: 1,用malloc类的函数分配内存; 2,用这些内存支持应用程序 3,用free函数释放内存 二、动态内存分配函数 malloc :从堆上分配内存 realloc : 在之前分配的内存块的基础上,将内存... -
分享一个结构体指针动态分配内存的C语言程序
2020-02-16 18:19:04C语言中不支持用变量来定义数组的个数,因此C语言中想要动态分配内存,常用的方法是指针+malloc()\calloc()\realloc()的方式。 这里仅针对结构体指针+calloc()实现“动态结构体数组”。这里之所以称之为”动态... -
C++ 动态分配内存
2016-10-01 15:16:47静态方法:变量所占的内存空间不需要程序员自己管理,编译器在编译阶段自动将管理这些空间的代码加入到目标文件中,程序运行时,由操作系统自动为变量分配内存单元,在变量的生存期内,...动态分配内存:程序运行时根 -
C语言: 动态分配内存
2019-12-14 17:22:33动态分配内存 动态分配,是指用户可以在程序运行期间根据需要申请或释放内存,大小也完全可控。动态分配不像数组内存那样需要预先分配空间,而是由系统根据程序需要动态分配,大小完全按照用户的要求来,当使用完毕... -
C语言的动态分配内存
2019-08-22 20:01:37C语言的动态分配内存 静态内存分配 定义:在C语言的程序空间中,可知代码区、常量区、全局数据区的内存在程序启动时就已经分配好了,这些地址空间大小固定,不能由程序分配和释放,只能等程序运行结束由系统来... -
C和C++中动态分配内存、程序占用内存的种类
2014-06-29 13:31:14c是malloc和free, c++是new和delete,(C++面向对象的) 区别如下: ...(1)new、delete 是操作符,可以重载,只能在C++中使用。...(2)malloc、free是函数,可以覆盖,...(4)malloc仅仅分配内存,free仅仅回收内 -
05 动态分配内存
2017-05-05 12:40:45如果进程一直不退,动态分配越来越多的空间,会引起系统可用内存不足,这就是内存泄漏。 注意:分配在堆里的空间,所在函数执行结束也不会自动回收分配在堆里的空间(会自动回收栈里分配的空间).只有调用回收... -
动态分配与静态分配内存
2019-05-06 12:11:15内存的静态分配和动态分配的区别主要是两个: 一是时间不同。静态分配发生在程序编译和连接的时候。动态分配则发生在程序调入和执行的时候。 二是空间不同。堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:... -
malloc动态分配内存和free释放内存
2020-06-23 21:09:33malloc动态分配内存和free释放内存 malloc 动态分配的内存在堆区,其空间并不连续。函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,... -
用new和delete运算符动态分配内存空间的方法编写程序。
2012-05-17 11:11:47用new和delete运算符动态分配内存空间的方法编写程序。从键盘输入33整型数组的数据,并计算出所有元素之和,打印出最大值和最小值。输入输出要用流运算符实现。 -
转 静态分配和动态分配内存的区别
2019-09-17 08:40:43说白了,内存的静态分配和动态分配的区别主要是两个: 一是时间不同。静态分配发生在程序编译和连接的时候。动态分配则发生在程序调入和执行的时候。 二是空间不同。堆都是动态分配的,没有静态分配的堆。栈有2种... -
C语言中动态分配内存
2017-08-15 09:22:33在使用c语言编写程序时,经常遇到数组长度不固定,或者需要由前面计算结果给出所需数组长度的情况,此时就需要用到C语言中的动态分配内存。动态分配内存主要用到三个函数malloc,memset 和 free。 void ... -
常见动态分配内存分配函数
2015-09-11 11:16:221.malloc函数的使用方法 : ...stdlib.h中,作用是在内存的堆区分配一个大小为size的连续空间,如果分配内存成功,函数返回新分配内存的首地址,否则,返回NULL,注意:鉴于上述这点,一般在写程序需要判断分 -
静态分配和动态分配内存的区别
2016-12-05 22:31:12说白了,内存的静态分配和动态分配的区别主要是两个: 一是时间不同。静态分配发生在程序编译和连接的时候。动态分配则发生在程序调入和执行的时候。 二是空间不同。堆都是动态分配的,没有静态分配的堆。... -
C语言杂谈——动态分配内存
2017-01-05 19:42:00所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。 动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要... -
C++ | 动态分配内存 new和malloc的区别
2020-03-20 22:19:48动态分配内存是指程序在运行时才提出分配内存的要求,主要目的是让内存运用更有弹性。 动态分配内存后必须在程序结束前完成释放内存的操作。 如果程序运行期间分配的内存未释放,就会造成内存空间的浪费,形成所谓的... -
动态分配内存空间过程
2013-10-19 22:10:22动态分配内存空间过程 本篇文章仅以一个非常短小的程序进行讲解。 C编译系统提供4个内存动态分配函数:calloc(),malloc()用于动态申请内存空间,realloc()用于重新改变已分配的动态内存空间的大小,free()用于... -
【存储类和动态内存分配】 程序内存的三个独立部分
2019-03-28 20:53:10③ 动态分配的内存 在编译的时候就已经知道了静态存储时期存储类变量所需的内存数量,存储在这一部分的数据在整个程序运行期间都可使用。这一类型的每个变量在程序开始时就已存在,到程序结... -
C语言动态分配内存
2016-05-21 14:09:37动态存储分配 在数组一章中,曾介绍过数组的长度是预先定义好的,在整个程序中固定不变。C语言中不允许动态数组类型。 例如: int n; scanf(“%d”,&n); int a[n]; 用变量表示长度,想对数组的大小作动态说明... -
C语言动态分配内存实例
2018-04-04 21:42:22有些数组的长度只有在运行时才知道,所以就用到了动态分配内存,下面的程序就是来演示读取一列整数,并按升序进行排列,并打印出来。/* ** 读取,排序,打印一列整数值 */ #include <stdlib.h> #... -
动态分配内存,不释放,程序退出后会被系统回收吗
2020-04-05 11:42:23对于MAC OS,Linux,Windows系统,malloc 的请求系统都知道,程序退出时,系统会回收malloc 的所有资源。这个是编译器智能释放内存。当然有些内存系统是...所谓动态内存,是由malloc系列函数进行申请的内存,除非在...