刚学C++内存分配,对建立链表的疑问

C++语言 码拜 8年前 (2016-09-15) 2228次浏览
刚刚学C++内存分配。回头看本人写的链表,产生了疑问。
函数返回值不可以是局部变量的指针或引用,原因是当函数结束后局部变量被释放,那么指针将指向一个无效的内容(指针指向空间不变,但空间内容没有了)
那么为什么在建立链表返回头结点指针时却没发生这种问题。
其实链表的各个节点的空间都是在函数内建立的,包括头结点。
头结点的空间不应该在函数结束后释放么,导致头结点指针指向一个无效的空间,对其它节点也是这样
下面这句
newNodePtr = ( list* )malloc( sizeof( list ) ) ;
newNodePtr->element = data ;
newNodePtr->next = NULL ;
head = newNodePtr ;
函数结束后head指向的空间不会被释放掉么?头结点空间也是局部建立的啊?

#include <iostream>
#include <stdlib.h>
typedef struct Node  list ;
struct Node 
{
	int element ;
	struct Node *next;
} ;
using namespace std ;
list* creatList(    )
{
	int data   ;
	list *head ;
	list *rearPtr ,*newNodePtr ;

	head = NULL ;
	while ( scanf("%d",&data) && data!=0 )
	{
		if( head == NULL )
		{
			newNodePtr = ( list* )malloc( sizeof( list ) ) ;
			newNodePtr->element = data ;
			newNodePtr->next = NULL ;
			head = newNodePtr ;
			rearPtr = head  ;
		}
		else 
		{
			newNodePtr = ( list* )malloc( sizeof( list ) ) ;
			newNodePtr->element = data ;
			newNodePtr->next = NULL ;
			rearPtr->next = newNodePtr ;
			rearPtr = newNodePtr ;//rearPtr永远指向尾节点
		}
	}
	return head ;
}
void outPut( list *head  )
{
	if( head == NULL )
		printf("链表为空\n");
	else 
		while( head != NULL )
		{
			printf("%d  ",head->element  ) ;
			head = head->next ;
		}
	printf("\n") ;
}
list* reverseList( list *head  )
{
	list *reverHead ;
	list *t ;
	reverHead = NULL ;
	while( head!=NULL )
	{
		t = head->next ;
		head->next = reverHead ;
		reverHead = head ;
		head = t ;
	}
	return reverHead ;
}
int main(  )
{
	list *head ;
    head = creatList(   ) ;
	cout<<"原链表序列"<<endl ;
	outPut( head ) ;
    head = reverseList( head ) ;
	cout<<"逆转后的链表序列"<<endl ;
	outPut( head ) ;
	return 0 ;
}
解决方案

5

你得先去理解一下内存的划分,堆,栈,静态区等;
链表里面new出来的结点存在堆上,函数结束是不会释放的,只有手动调用delete才会被释放

5

动态分配的(new ,c里边是malloc)需要程序员本人手动释放(delete,c对应的是free),也就是说不管在哪里new的,都一直保持有效。

2

你要学习下内存知识,使用new和malloc()分配的内存空间,只要进程不结束(无论以什么方式结束),或没有被手动释放,都不会被释放

10

一个由C/C++编译的程序占用的内存分为以下几个部分:
1、栈区(stack):又编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式相似于数据结构的栈。
2、堆区(heap):一般是由程序员分配释放,若程序员不释放的话,程序结束时可能由OS回收,值得注意的是他与数据结构的堆是两回事,分配方式倒是相似于数据结构的链表。malloc和new出来的空间就属于堆区。
3、全局区(static):也叫静态数据内存空间,存储全局变量和静态变量,全局变量和静态变量的存储是放一块的,初始化的全局变量和静态变量放一块区域,没有初始化的在相邻的另一块区域,程序结束后由系统释放。
4、文字常量区:常量字符串就是放在这里,程序结束后由系统释放。
5、程序代码区:存放函数体的二进制代码。

3

1)函数的返回值,不可以是局部(非静态)变量的地址,或引用
–跟指针没关系–
原因是,局部(非静态)变量生命周期,不出函数。
一旦函数返回,则这个变量不可用了(生命周期结束)
返回他的地址,或引用,以求在函数调用结束后使用变量。
其实用的是变量的僵尸,而不是变量本身。
而这块内存,还可能,会被其他用途占用,
这样,就会使用造成程序混乱。
2)动态分配的内存(堆内存)并不是函数的局部(非静态)变量
确切的说,堆内存,是对程序员来说,一块没有名字的内存区域
这块内存本身,程序员是可以使用的,
但是要通过内存管理程序,进行分配,不用了要适时回收。
它本身,其实相当于全局变量。
所以生命周期,跟函数无关。
任何时候,只要没有回收,
读写都是可以的(只要不越界读写)

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明刚学C++内存分配,对建立链表的疑问
喜欢 (0)
[1034331897@qq.com]
分享 (0)