關於,函數調用是傳值調用,初始化函數中重新分配內存,導致形參的值和實參的值不一致 問題分析

今天遇到一個問題:

#define true 1
#define false 0
#define ok 1
#define error 0
#define infeasible -1
#define overflow -2
#include<stdio.h>
#include<malloc.h>
typedef char ElemType;
typedef int Status;

typedef struct LNode
{
    ElemType data;
    struct LNode * next;
} LNode,*LinkList;

void CreateList_HeadInsert(LinkList L)//頭插法
{
    //建立帶表頭結點的單鏈表線性表L.
    LinkList p;
    char ch;
    ch=getchar();
    while(ch!='\n')
    {
        p=(LinkList)malloc(sizeof(LNode));
        p->data=ch;
        p->next=L->next;//插入第一個結點的時候L->next爲null;
        L->next=p;
        ch=getchar();
    }
}

void InitList(LinkList L)//初始化,創建頭結點;
{
    L=(LinkList)malloc(sizeof(LNode));//頭指針指向剛分配的地址;
    L->next=NULL;//創建一個帶頭結點的單鏈表;
}
void main()
{
    LinkList L;
    InitList(L);//初始化單鏈表;
    CreateList_HeadInsert(L);//頭插法建單鏈表
    // p=L->next;
    while(L->next!=NULL)
    {
        printf("%c",L->next->data);
        L=L->next;
    }
}

函數執行到creat函數,L->next=p;時,發生段錯誤。怎麼修改也沒找到錯誤原因;

後看到回覆:函數調用是傳值調用,初始化函數中重新分配內存,導致形參的值和實參的值不一致,也就是main函數中的L->next沒有被設置爲NULL.去掉內存分配後,實參的next和形參的next指向同一位置,形參的next的變化同時導致實參的next的變化.

恍然大悟:在initlist初始化函數中,把指針L作爲形參傳到函數中的只是指針L的值,在函數中只能調用,但是不能修改。

malloc申請內存,即修改了指針的值,指向了別處,對指針L操作不在起左右,以後要避免這樣的錯誤;

修改函數如下:

#include<stdio.h>
#include<malloc.h>
#include <string.h>
#include <stdlib.h>
#define true 1
#define false 0
#define ok 1
#define error 0
#define infeasible -1
#define overflow -2
typedef char ElemType;
typedef int Status;

typedef struct LNode
{
    ElemType data;
    struct LNode * next;
} LNode,*LinkList;

LinkList head;  //定義頭指針
void CreateList_HeadInsert(LinkList L)//頭插法
{
    //建立帶表頭結點的單鏈表線性表L.
    LinkList p;
    char ch;
    ch=getchar();
    while(ch!='\n')
    {
        p=(LinkList)malloc(sizeof(LNode));
        p->data=ch;
       //p->next=L->next;//插入第一個結點的時候L->next爲null;
        p->next = NULL;
        L->next=p;
        L = p;
        getchar();//注意,此處添加getchar()吸收回車符;
        ch=getchar();
    }
}
/*
 *函數調用是傳值調用,初始化函數中重新分配內存,導致形參的值和實參的值不一致
void InitList(LinkList L)//初始化,創建頭結點;
{
    L=(LinkList)malloc(sizeof(LNode));//頭指針指向剛分配的地址;
    L->next=NULL;//創建一個帶頭結點的單鏈表;
}
*/
void main()
{
    LinkList L;
    L=(LinkList)malloc(sizeof(LNode));//頭指針指向剛分配的地址;
    L->next=NULL;//創建一個帶頭結點的單鏈表;
    head = L;
    // InitList(L);//初始化單鏈表;
    CreateList_HeadInsert(L);//頭插法建單鏈表
    // p=L->next;
    while(L->next!=NULL)
    {
        printf("%c",L->next->data);
        L=L->next;
    }
    putchar('\n');
}

執行:

[root@bogon home]# ./t5
q
w
e
r
t

qwert


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