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;
}
5
задан Suugaku 11 May 2010 в 18:40
поделиться

3 ответа

Вы получаете сегмент, потому что 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;
}
10
ответ дан 18 December 2019 в 08:27
поделиться

Опубликованный код имеет неопределенное поведение. Помимо рекурсии, вы говорите:

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

Другими словами, вы пытаетесь вывести на неинициализированный указатель, что является неопределенным поведением и, следовательно, бессмысленно.

Если вы спрашиваете, могу ли я использовать sprintf в рекурсивной функции для добавления информации в буфер, ответ возможен, но нелегко. Вам нужно будет поддерживать буфер при каждом рекурсивном вызове, а также индекс буфера, который будет обновляться при каждом вызове.

3
ответ дан 18 December 2019 в 08:27
поделиться

Вы не выделили никакой памяти для out, поэтому вы пишете в случайную область памяти. Этот алгоритм кажется немного шатким с этой точки зрения - как вы узнаете, сколько места нужно выделить для out - вы знаете какие-то границы размера дерева?

6
ответ дан 18 December 2019 в 08:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: