@@ -114,9 +114,13 @@ class cpp_function : public function {
114114 object name () const { return attr (" __name__" ); }
115115
116116protected:
117+ using unique_function_record = std::unique_ptr<detail::function_record, void (*)(detail::function_record *)>;
118+
117119 // / Space optimization: don't inline this frequently instantiated fragment
118- PYBIND11_NOINLINE std::unique_ptr<detail::function_record> make_function_record () {
119- return std::unique_ptr<detail::function_record>(new detail::function_record ());
120+ PYBIND11_NOINLINE unique_function_record make_function_record () {
121+ // `destruct<true>(function_record)`: `initialize_generic` copies strings and
122+ // takes care of cleaning up in case of exceptions.
123+ return unique_function_record (new detail::function_record (), destruct<false >);
120124 }
121125
122126 // / Special internal constructor for functors, lambda functions, etc.
@@ -247,7 +251,7 @@ class cpp_function : public function {
247251 };
248252
249253 // / Register a function call with Python (generic non-templated code goes here)
250- void initialize_generic (std::unique_ptr<detail::function_record> &&unique_rec, const char *text,
254+ void initialize_generic (unique_function_record &&unique_rec, const char *text,
251255 const std::type_info *const *types, size_t args) {
252256 auto rec = unique_rec.get ();
253257
@@ -486,6 +490,7 @@ class cpp_function : public function {
486490 }
487491
488492 // / When a cpp_function is GCed, release any memory allocated by pybind11
493+ template <bool DeleteStrings = true >
489494 static void destruct (detail::function_record *rec) {
490495 // If on Python 3.9, check the interpreter "MICRO" (patch) version.
491496 // If this is running on 3.9.0, we have to work around a bug.
@@ -497,14 +502,19 @@ class cpp_function : public function {
497502 detail::function_record *next = rec->next ;
498503 if (rec->free_data )
499504 rec->free_data (rec);
500- std::free ((char *) rec->name );
501- std::free ((char *) rec->doc );
502- std::free ((char *) rec->signature );
503- for (auto &arg: rec->args ) {
504- std::free (const_cast <char *>(arg.name ));
505- std::free (const_cast <char *>(arg.descr ));
506- arg.value .dec_ref ();
505+ // During initialization, these strings might not have been copied yet,
506+ // so they cannot be freed. Once the function has been created, they can.
507+ if (DeleteStrings) {
508+ std::free ((char *) rec->name );
509+ std::free ((char *) rec->doc );
510+ std::free ((char *) rec->signature );
511+ for (auto &arg: rec->args ) {
512+ std::free (const_cast <char *>(arg.name ));
513+ std::free (const_cast <char *>(arg.descr ));
514+ }
507515 }
516+ for (auto &arg: rec->args )
517+ arg.value .dec_ref ();
508518 if (rec->def ) {
509519 std::free (const_cast <char *>(rec->def ->ml_doc ));
510520 // Python 3.9.0 decref's these in the wrong order; rec->def
0 commit comments