C: спринтф и рекурсия - PullRequest
5 голосов
/ 11 мая 2010

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

Ответы [ 3 ]

10 голосов
/ 11 мая 2010

Вы получаете сегмент, потому что 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;
}
6 голосов
/ 11 мая 2010

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

3 голосов
/ 11 мая 2010

Код при публикации имеет неопределенное поведение. кроме рекурсии вы говорите:

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

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

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

...