C: sprintf 和递归

发布于 2024-09-01 12:22:55 字数 573 浏览 7 评论 0原文

在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;
}

In C, is it possible to use recursion within the sprintf function ? For some reason I get a segmentation fault when I do it:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

日暮斜阳 2024-09-08 12:22:55

您获得段是因为 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;
}

You're getting segment because out is not initialized, not because of the recursion. You should allocate some memory for it, e.g.

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;
}
夕嗳→ 2024-09-08 12:22:55

您没有为 out 分配任何内存,因此您正在写入随机内存位置。这个算法在这方面似乎有点不稳定 - 你如何知道为 out 分配多少空间 - 你知道树上的一些大小界限吗?

You didn't allocate any memory for out, so you're writing into a random memory location. This algorithm seems a bit shaky on that front - how will you know how much space to allocate for out - do you know some size bounds on the tree?

荒人说梦 2024-09-08 12:22:55

发布的代码具有未定义的行为。除了递归之外,您是在说:

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

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

如果您问,我可以在递归函数中使用 sprintf 向缓冲区添加信息吗?答案是可能的,但并不容易。您必须在每个递归调用之外维护一个缓冲区,以及每个调用将更新的缓冲区的索引。

The code as posted has undefined behaviour. recursion aside you are saying:

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

In other words you are trying to output to an uninitialised pointer, which is undefined behaviour, and thus is meaningless.

If you are asking, can I use sprintf in a recursive function to add information to a buffer, the answer is possibly, but not easily. You would have to maintain a buffer outwith each recursive call and also an index to the buffer that each call would update.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文