學習之路:指針犯的錯誤

指針是學習數據結構的基礎,,c語言之所以強大,以及其自由性,很大部分體現在其靈活的指針運用上。因此,說指針是c語言的靈魂,一點都不爲過。
同時數據結構的實現大部分都離不開指針。
最近實現隊列本來以爲十拿九穩,沒想到怎麼都調不過。
隊列定義

typedef struct 	Queue
{
	struct QueNode * _leader;
	struct QueNode * _tail;
}Queue;

節點定義

typedef struct 	QueNode 
{
	Quetypedef data;
	struct 	QueNode *_next;
}QueNode;

初始化

void QueueInit(Queue *pq)
{
	assert(pq);
	pq->_leader=pq->_tail = NULL;
}

插入隊列
上面的都能實現,但是到插入就有問題了,這是我開始時候的代碼


void PushQueue(Queue *pq,Quetypedef x)
{
	if(pq->_leader == NULL)
	{
		pq->_leader-_data = pq->_tail->_data = x;
	}
	else
	{
		pq->_tail->_next = x;
		pq->_tail  =  pq->_tail->_next;
	}
}

結果程序總是崩潰,但是我的邏輯上是沒有問題的,插入數據到一個隊列,如果隊列爲空則讓整個隊列的頭和尾都爲這個值,否則頭節點不動,尾節點向後移動。
後來才發現忘記了malloc函數,相當於指針只有看的權限,沒有修改的權限,所以程序會崩潰

void PushQueue(Queue *pq,Quetypedef x)
{
	if(pq->_leader == NULL)
	{
		pq->_leader = pq->_tail = BuyNode(x);
	}
	else
	{
		pq->_tail->_next = BuyNode(x);//BuyNode(x)功能是分配節點
		pq->_tail  =  pq->_tail->_next;
	}
}

分配節點的代碼

QueNode *BuyNode(Quetypedef x)
{
	QueNode* QNew = (QueNode*)malloc(sizeof(QueNode));
	QNew->data = x;
	QNew->_next = NULL;
	return QNew;
}

然後我在想malloc函數是讓指針有權限修改分配的內存,還是讓這段內存變成可修改的內存

#include <stdio.h>
#include <malloc.h>
int main()
{
	int *a;
	a = (int*)malloc(sizeof(int));
	*a = 3;
	printf("%d",*a);
		int *b = a;
	printf("%d",*b);
	}

程序運行成功,說明malloc函數分配的內存空間是可修改的,而不是讓指針有了修改權限
C99中規定malloc用於申請一塊連續的指定大小的內存塊區域以void*類型返回分配的內存區域地址,當無法知道內存具體位置的時候,想要綁定真正的內存空間,就需要用到動態的分配內存。
除此之外還有一個踩的坑,我開始寫的釋放節點的代碼


free(pq->_leader);
		pq->_tail = NULL;
		pq->_leader = NULL; 

我就想如果釋放一個空指針按理來說程序會崩潰,因爲free函數是找到指針指向的空間,而對於一個空指針的操作必然會引起程序的崩潰,但是加上後程序運行成功,在查到了C99規定
**C99:將null指針傳遞給free或者cfree在傳統實現中由實現定義其行爲。新版本中調用無意義。
**也就是說這段代碼沒有實際作用
總結:指針可以指向任意地址,但是隻能修改malloc分配的有效地址,否則會程序崩潰
free(NULL)不會導致程序崩潰,但是代碼本身無意義

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章