使用new创建动态结构和自动, 静态, 动态三种存储方式
2011-03-09 10:07
429 查看
1. 有些时候在运行时创建数组由于在编译时创建数组(有些时候不是这样, 比如使用OpenGL绘图和GPU并行计算结合的时候, 需要将大量的数据传送到显存, 每次计算完又要传送回宿主机渲染, 但并不是要传送回所以值, 有些值可以仍然留在显存中, 对于这些值, 显然一次创建最恰当, 使用静态数组最合适, 当然使用动态数组也可以, 但是只需创建一次就可以了), 对于结构体也是这样.
2. C++中的结构体. 有两种方式, 一种是动态方式, 一种是静态方式. 使用new一般是动态方式, 一般是与指针搭配, 静态方式是直接声明的.
struct price{
int apple;
int orange;
};
静态方式, 是结构体类型数据, 类似于int类型数据的声明方式, 如price p1={100,200};或者price p1; p1.apple=100; p1.orange=200; 静态方式是结构体类型数据, 访问结构体成员的时候采用句点操作符, 例如p1.apple, p1.orange.
动态方式, 结构体指针类型数据, 采用箭头操作符访问结构体成员, 如price * p2=new price; p2->apple=100; p2->orange=200; 当然也可以通过这样的方式采用句点操作符访问结构体成员. 例如对于结构体指针price *p3=new price;(这里创建了一个结构体, 将结构体的首地址返回给等号右边, 并赋给指向此结构体的指针p3, 不能直接写成price *p3, 这样只是创建了一个指针, 并没有创建结构体), p3是指向结构体的指针, 那么使用解除引言操作符*可以得到结构体本身, 即*p3是结构体本身, 那么访问成员的方式可以这样(*p3).apple, (*p3).orange.
3. 使用new动态分配内存, 并释放内存一遍重新使用. 下面的代码使用了返回指针的函数.
4. 三种存储方式: 自动存储, 静态存储, 动态存储.
自动存储: 函数内部定义的常规变量使用自动存储空间, 称为自动变量(也称局部变量), 如getname函数中的temp, pn. 他们在所属的函数被调用时自动产生, 在该函数结束时消亡, 例如getname函数中的temp只在getname函数被调用时存在, 当调用结束时, temp使用的内存将被自动释放, 如果getname返回temp的地址, 则main函数name指向的内存将很快被重新使用, 因此我们必须在getname中使用new并获取一个副本.
静态存储: 静态存储是在整个程序执行期间都存在的存储方式, 在函数外声明它或者使用关键字static.
动态存储: new和delete提供了比自动变量和静态变量更灵活的方法. 他们管理一个内存池, 也成为自由存储空间. 内存池通用语静态变量和自动变量的内存是分开的. new和delete使程序员对程序如何使用内存有更大的控制权.
5. 堆栈, 堆和内存泄漏. 如果使用了new, 没有调用delete, 即使包含指针的内存由于作用域规则和对象生命周期的原因而被释放, 但是在自由存储空间上动态分配的变量或者结构也将继续存在, 但是将会无法访问这些内存, 因为指向这些内存的指针无效了.这将导致内存泄漏. 被泄漏的内存将在程序的整个生命周期内斗不可使用, 这些内存被分配出去, 但无法收回, 可能导致可用内存耗尽, 程序崩溃. 我们要养成一种好习惯, 成对的使用new和delete, 在自由存储空间上动态分配内存, 随后便释放它.
2. C++中的结构体. 有两种方式, 一种是动态方式, 一种是静态方式. 使用new一般是动态方式, 一般是与指针搭配, 静态方式是直接声明的.
struct price{
int apple;
int orange;
};
静态方式, 是结构体类型数据, 类似于int类型数据的声明方式, 如price p1={100,200};或者price p1; p1.apple=100; p1.orange=200; 静态方式是结构体类型数据, 访问结构体成员的时候采用句点操作符, 例如p1.apple, p1.orange.
动态方式, 结构体指针类型数据, 采用箭头操作符访问结构体成员, 如price * p2=new price; p2->apple=100; p2->orange=200; 当然也可以通过这样的方式采用句点操作符访问结构体成员. 例如对于结构体指针price *p3=new price;(这里创建了一个结构体, 将结构体的首地址返回给等号右边, 并赋给指向此结构体的指针p3, 不能直接写成price *p3, 这样只是创建了一个指针, 并没有创建结构体), p3是指向结构体的指针, 那么使用解除引言操作符*可以得到结构体本身, 即*p3是结构体本身, 那么访问成员的方式可以这样(*p3).apple, (*p3).orange.
3. 使用new动态分配内存, 并释放内存一遍重新使用. 下面的代码使用了返回指针的函数.
#include <iostream> #include <cstring> using namespace std; char * getname() //返回指向输入字符串的指针 { //子函数里面分配的内存temp是在栈里面,子函数结束调用后会自动释放, 如果不让他释放,就要在子函数里使用malloc或者new, 子函数里分配的内存在子函数结束调用后才不会自动释放掉,但是如果main函数结束后,所以得内存都会被释放. char temp[80];//假设最多输入80个 cout<<"Enter name: "; cin>>temp; char *pn=new char[strlen(temp)+1];//分配合适的内存数,子函数调用后不会自动释放 strncpy(pn,temp,80);//拷贝temp指向的数据给pn指向的内存空间 return pn; //返回指向包含输入字符串的指针 } int main() { char *name; name=getname();//name指向输入字符串 //从name开始打印字符,知道遇到空字符为止,并输出字符串的首地址 cout<<name<<" at "<<(int *)name<<endl; delete [] name; //释放子函数getname里面分配的内存 name=getname();//再次调用子函数 cout<<name<<" at" <<(int *)name<<endl; delete [] name; return 0; }
4. 三种存储方式: 自动存储, 静态存储, 动态存储.
自动存储: 函数内部定义的常规变量使用自动存储空间, 称为自动变量(也称局部变量), 如getname函数中的temp, pn. 他们在所属的函数被调用时自动产生, 在该函数结束时消亡, 例如getname函数中的temp只在getname函数被调用时存在, 当调用结束时, temp使用的内存将被自动释放, 如果getname返回temp的地址, 则main函数name指向的内存将很快被重新使用, 因此我们必须在getname中使用new并获取一个副本.
静态存储: 静态存储是在整个程序执行期间都存在的存储方式, 在函数外声明它或者使用关键字static.
动态存储: new和delete提供了比自动变量和静态变量更灵活的方法. 他们管理一个内存池, 也成为自由存储空间. 内存池通用语静态变量和自动变量的内存是分开的. new和delete使程序员对程序如何使用内存有更大的控制权.
5. 堆栈, 堆和内存泄漏. 如果使用了new, 没有调用delete, 即使包含指针的内存由于作用域规则和对象生命周期的原因而被释放, 但是在自由存储空间上动态分配的变量或者结构也将继续存在, 但是将会无法访问这些内存, 因为指向这些内存的指针无效了.这将导致内存泄漏. 被泄漏的内存将在程序的整个生命周期内斗不可使用, 这些内存被分配出去, 但无法收回, 可能导致可用内存耗尽, 程序崩溃. 我们要养成一种好习惯, 成对的使用new和delete, 在自由存储空间上动态分配内存, 随后便释放它.
相关文章推荐
- 1.5 使用new创建动态结构和自动, 静态, 动态三种存储方式
- C++ 静态二维数组与new出来的动态二维数组,存储结构的差别
- 正确得到线程退出信息的方法详解-变量存储退出信息结构、使用动态存储的方式退出信息结构、使用全局变量方式推相互信息结构、使用main函数中的局部变量存储退出信息结构
- iPhone开发之创建简单界面视图的三种方式之一 使用xcode4自动生成界面
- 【C++学习笔记】使用new创建动态结构
- 使用new创建动态结构
- c++ primer plus 习题5.7(使用new为结构创建动态数组)
- C++中的数据存储方式自动存储、静态存储和动态存储
- 使用js改变DOM样式的三种方式 - 动态创建style标签
- Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)
- C++使用new创建动态结构
- 一个jsp页面引入另一个jsp页面的三种方式 及静态引入和动态引入的区别
- 使用new来为动态分配结构数组并赋值
- 使用Gradle自动创建Java项目结构
- linux三种方式使用库:静态链接库,动态链接库,动态加载库
- 使用ioc来创建对象有三种方式
- new的三种使用方式:plain new、nothrow new、placement new.
- 使用内部线程类创建线程的三种方式的模板
- Jquery mobile按钮的三种创建方式及使用条件
- 使用C#创建webservice及三种调用方式 (ASP.NETweb编程常用到的27个函数集)