This appears to be... an attempt to call a function named preorder, that accepts itself as a parameter? What are you trying to do with this line? preorder = preorder(tree->left, preorder);
preorder = preorder(tree->left, preorder); should be preorder = value(tree->left, preorder); and the same with the call to tree->right.
Notice that you're passing preorder by value. That means it gets copied each time you call value, and that will take a whole lot of time as the tree gets larger. Instead, you should pass it by reference and return void:
Notice that I've changed the nullptr check to check tree instead of tree->right and tree->next. This makes the code shorter at the expense of extra calls. More importantly though, it fixes a bug: now you call value on an empty tree.
You can do a similar trick to greatly reduce the code in insert_tree(). Once you have the code working, save a copy and then see if you can shrink insert_tree().