C++中的内存分配的问题
2016-02-27 12:17
225 查看
C++中类和结构体的对象声明有两种方式:
直接声明的方式:
这种方式声明的变量
使用new的方式:
这种方式是创建在堆区的,是要程序员自己申请管理,系统不会自动回收。需要使用
下面看一段程序:
上面这段程序的本意是要创建一个链表,0,1,2,3,4;但是最后的显示结果是:0,4
通过单步调试,查看变量地址信息,发现在进入循环后使用上述第一种方式创建的
本以为是应该每次申请一个新的变量的地址都不同的,但是事实告诉我们是相同的地址。猜测应该是变量名称相同,然后地址分配成了相同的地址。为了验证一些,做了如下测试:
这一次的结果正确了,因为不同的变量名称分配到了不同的地址,不会出现变量地址覆盖的问题。
或者使用
直接声明的方式:
Node nodes;
这种方式声明的变量
nodes是创建在栈区的。由系统自动回收。
使用new的方式:
Node *nodes=new Node;
这种方式是创建在堆区的,是要程序员自己申请管理,系统不会自动回收。需要使用
delete回收。
下面看一段程序:
int main() { //create Linklist Node nodes; Node* node=&nodes; nodes.val=0; for(int i=1;i<5;i++) { Node nodei; nodei.val=i; node->next=&nodei; node=node->next; } node->next=NULL; printf("link list:\n"); Node* cur=&nodes; while(cur!=NULL){ printfn cur=cur->next; } }
上面这段程序的本意是要创建一个链表,0,1,2,3,4;但是最后的显示结果是:0,4
通过单步调试,查看变量地址信息,发现在进入循环后使用上述第一种方式创建的
Node变量每一次的地址都是相同的。
(gdb) p &nodei $2 = (Node *) 0x7fffffffde50 (gdb) p &nodei $3 = (Node *) 0x7fffffffde50 (gdb) c Continuing. Breakpoint 1, main () at getPenultimate_KNode.cpp:107 107 nodei.val=i; (gdb) p &nodei $4 = (Node *) 0x7fffffffde50 (gdb) p &nodei $3 = (Node *) 0x7fffffffde50 (gdb) c Continuing. Breakpoint 1, main () at getPenultimate_KNode.cpp:107 107 nodei.val=i; (gdb) p &nodei $4 = (Node *) 0x7fffffffde50
本以为是应该每次申请一个新的变量的地址都不同的,但是事实告诉我们是相同的地址。猜测应该是变量名称相同,然后地址分配成了相同的地址。为了验证一些,做了如下测试:
int main() { //create linklist Node node0; Node* node=&node0; node0.val=0; Node node1; node1.val=1; node->next=&node1; node=node->next; Node node2; node2.val=2; node->next=&node2; node=node->next; node->next=NULL; printf("link list:\n"); Node* cur=&node0; while(cur!=NULL){ printf("%i\n",cur->val); cur=cur->next; } }
这一次的结果正确了,因为不同的变量名称分配到了不同的地址,不会出现变量地址覆盖的问题。
或者使用
new的方式来申请新的
Node,这样每次申请的都是新的内存地址。
void LinkList::create(){ int temp; cin>>temp; Node* p=head; while(temp!=-1){ Node *newNode=new Node; newNode->val=temp; newNode->next=NULL; //connect to link list p->next=newNode; p=p->next; //otherwise, it will in a infinite loop cin>>temp; } }
相关文章推荐
- USACO1.2:dualpal
- Effective C++学习笔记 条款07:为多态基类声明virtual析构函数
- 《Effective C++》Rule36:绝不重新定义继承而来的non-virtual函数
- USACO1.1:friday
- C语言程序设计现代方法第二版基础部分读书笔记(【美】K.N.King 著)
- C++:private成员的访问
- C语言函数sscanf()的用法
- VS2015用C++创建的动态库导出函数名乱码原因分析
- C语言实现logistic回归
- C++基础总结(1)--基本数据类型范围
- C++基础总结(1)--基本数据类型范围
- C++: 解释error: call of overloaded ‘abs(int)’ is ambiguous
- Java JNI调用c语言的dll测试
- c++ virtual
- C语言书籍推荐
- C++中的namespace
- C语言之基本算法09—各位全是a的数列之和
- C++笔记:1
- C++开发人脸性别识别教程(15)——搭建MFC框架启动摄像头
- 【C++】Accessor and Mutator Functions & 函数形参与类私有成员重名的解决方法