2015-10-10 36 views
1

该程序包含链接列表的典型节点结构(所以指向下一个节点的指针和包含值的int)。我有以下测试功能:传递给函数时分配空指针

void F(NODE** Y, int value) 
{ 
    NODE* X = *Y; 

    if(!X) 
    { 
     printf("case1...\n"); 
     X = (NODE*)malloc(sizeof(NODE)); 
     X->Data = value; 
     return; 
    } 
    printf("case2...\n"); 
    X->Next = (NODE*)malloc(sizeof(NODE)); 
    X->Next->Data = value; 
    return; 
} 

void myPrint(NODE** Y) 
{ 
    NODE* X = *Y; 
    printf("printing...\n"); 

    printf("%d %d\n", X->Data, X->Next->Data); 
    return; 
} 

int main() 
{ 
    NODE* n = NULL; 

    F(&n, 5); 
    F(&n, 10); 

    myPrint(&n); 
} 

这段代码产生在Linux下面的输出:

case1... 
case1... 
printing... 
Segmentation fault 

我不明白为什么传递一个空指针的函数总会引起第一种情况发生。它看起来像指针被传递的价​​值,但我不认为这是怎么回事。如果我在main()内部的节点上调用malloc(),然后将它传递给F(),则第二种情况将会被击中,但不会是第一种情况。这对我来说至少是有意义的,因为当节点从main()传递到F()时节点永远不会为空,但显然在将节点传递给F()之前分配节点意味着F()内的空检查永远不会是真的。

我试图做甚至可能吗?有没有办法通过nF()而它是空的,并让它按照我想要的方式行事?或者我必须在F()之外分配n并删除F()里面的空检查?

+1

的功能名称“N”没有效果应该是功能做什么范围内有意义。通常这意味着函数名称具有活动动词(通常作为函数名称的第一部分)I.E. getValue()calcResult()等。所以这个函数:'F()'是没有意义的。甚至在我阅读函数之后,我不确定该函数应该做什么。 – user3629249

+0

调用函数:'malloc()'和函数系列时,1)不要转换返回的值,因为在C中,它是一个'void *',因此可以分配给任何指针,并且投射只会混淆代码并使维护更困难。 2)函数:'malloc()'和函数系列可能会失败。因此,请始终检查(!= NULL)返回的值以确保操作成功,否则失败将导致代码引用地址0x0000000000,这将导致未定义的行为并导致段错误事件 – user3629249

+3

您的根本问题是您不知道不明白'X'不是'n'的别名。 '* Y'是'n'的别名。当将'* Y'分配给'X'时,您将'n'的值分配给'X',而不是将'X'作为别名。 –

回答

2

在为X分配之后,您需要在函数F()中将其设置为*Y。否则,F()返回时不会反映出来。

所以我会改变代码

void F(NODE** Y, int value) 
{ 
    NODE* X = *Y; 

    if(!X) 
    { 
     printf("case1...\n"); 
     X = (NODE*)malloc(sizeof(NODE)); 
     X->Data = value; 

     *Y = X; //set the allocated pointer 
     return; 
    } 
    printf("case2...\n"); 
    X->Next = (NODE*)malloc(sizeof(NODE)); 
    X->Next->Data = value; 
    return; 
} 
+0

快2分钟...好表演。 –

+0

哇。我不能相信我错过了这一点。非常感谢你,这让我疯狂。这实际上让我质疑我在学校学到的一切。 – bha

0

在功能F()当在主()包含NULL的 'N';

该代码未将“n”的内容设置为指向malloc的内存。

更改包含在局部变量“X”值对在main()