2010-05-11 51 views
5

在C中,有可能在sprintf函数中使用递归吗?出于某种原因,我得到的,当我做一个分割故障:C:sprintf和递归

inline char *TreeNode_toString(const TreeNode *node) 
{ 
    char *out; 

    if(TreeNode_isExternal(node)) // If the node has no children... 
    { 
    sprintf(out, "%s:%.2f", node->name, node->distance); 
    } 
    else // The node is strictly binary, so it will have two non-null children 
    { 
    char *l = TreeNode_toString(node->l); // l = left child 
    char *r = TreeNode_toString(node->r); // r = right child 
    sprintf(out, "(%s,%s):%.2f", l, r, node->distance); 
    } 

    return out; 
} 

回答

10

你越来越细分,因为out未初始化不是递归的原因。你应该为它分配一些内存,例如

inline char *TreeNode_toString(const TreeNode *node) 
{ 
    char *out = malloc(4096); // <-- allocate 

    ... 

    char *l = TreeNode_toString(node->l); 
    char *r = TreeNode_toString(node->r); 
    snprintf(out, 4096, "(%s,%s):%.2f", l, r, node->distance); 
    // ^-- please use snprintf to avoid buffer overflow, thanks. 
    free(l); // <-- remember to free 
    free(r); // <-- remember to free 
    } 

    return out; 
} 
+0

你的意思是分配没有初始化 - out的说明值并不重要只是一些内存空间 – Mark 2010-05-11 18:43:37

6

你没有分配任何内存为out,所以你写入的随机内存位置。这个算法在前面看起来有点不稳定 - 你怎么知道要为out分配多少空间 - 你知道树上的一些大小边界吗?

+0

哦......谢谢你的答案。那么......我明白这个问题(我认为sprintf负责分配内存)......但我不知道如何解决它。在Java中它简单地是 public String toString(){ if(isExternal()) return name +“:”+ distance; else return“(”+ l.toString()+“:”+ r.toString +“)”; } – Suugaku 2010-05-11 18:49:17

3

发布的代码具有未定义的行为。递归抛开你说:

char * out; 
sprintf(out, "%s:%.2f", node->name, node->distance); 

换句话说,你正试图输出到一个未初始化的指针,这是不确定的行为,因此是毫无意义的。

如果你问,我可以在递归函数中使用sprintf将信息添加到缓冲区,答案可能但不容易。每次递归调用都必须保留一个缓冲区,并且每个调用都会更新缓冲区的索引。