Skip to content

Commit 2f8f1a7

Browse files
committed
Fix memory leak in TopoDS_Shape output typemaps
The TopoDS_Shape output typemaps were using direct return statements (Py_RETURN_NONE and return resultobj) which bypassed SWIG's cleanup code for input arguments. This caused memory leaks when functions taking std::string parameters returned TopoDS_Shape, as the temporary std::string objects were never freed. Changed to use $result assignment instead of direct returns, allowing SWIG to generate proper freearg cleanup code that calls "if (SWIG_IsNewObj(res)) delete arg" for temporary std::string objects.
1 parent 4954ef1 commit 2f8f1a7

1 file changed

Lines changed: 114 additions & 112 deletions

File tree

src/SWIG_files/common/FunctionTransformers.i

Lines changed: 114 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -138,128 +138,130 @@ Standard_Boolean & function transformation
138138
%typemap(out) TopoDS_Shape {
139139
TopoDS_Shape* sh = &$1;
140140
if (!sh || sh->IsNull()) {
141-
Py_RETURN_NONE;
141+
// Use $result instead of Py_RETURN_NONE to allow SWIG cleanup code to run
142+
$result = Py_None;
143+
Py_INCREF(Py_None);
142144
}
143-
PyObject *resultobj = nullptr;
144-
145-
switch (sh->ShapeType())
146-
{
147-
case TopAbs_COMPOUND: {
148-
TopoDS_Compound* ptr = new TopoDS_Compound(TopoDS::Compound(*sh));
149-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Compound, SWIG_POINTER_OWN | 0);
150-
if (!resultobj) delete ptr;
151-
break;
152-
}
153-
case TopAbs_COMPSOLID: {
154-
TopoDS_CompSolid* ptr = new TopoDS_CompSolid(TopoDS::CompSolid(*sh));
155-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_CompSolid, SWIG_POINTER_OWN | 0 );
156-
if (!resultobj) delete ptr;
157-
break;
158-
}
159-
case TopAbs_SOLID: {
160-
TopoDS_Solid* ptr = new TopoDS_Solid(TopoDS::Solid(*sh));
161-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Solid, SWIG_POINTER_OWN | 0 );
162-
if (!resultobj) delete ptr;
163-
break;
164-
}
165-
case TopAbs_SHELL: {
166-
TopoDS_Shell* ptr = new TopoDS_Shell(TopoDS::Shell(*sh));
167-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Shell, SWIG_POINTER_OWN | 0 );
168-
if (!resultobj) delete ptr;
169-
break;
170-
}
171-
case TopAbs_FACE: {
172-
TopoDS_Face* ptr = new TopoDS_Face(TopoDS::Face(*sh));
173-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Face, SWIG_POINTER_OWN | 0 );
174-
if (!resultobj) delete ptr;
175-
break;
176-
}
177-
case TopAbs_WIRE: {
178-
TopoDS_Wire* ptr = new TopoDS_Wire(TopoDS::Wire(*sh));
179-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Wire, SWIG_POINTER_OWN | 0 );
180-
if (!resultobj) delete ptr;
181-
break;
182-
}
183-
case TopAbs_EDGE: {
184-
TopoDS_Edge* ptr = new TopoDS_Edge(TopoDS::Edge(*sh));
185-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Edge, SWIG_POINTER_OWN | 0 );
186-
if (!resultobj) delete ptr;
187-
break;
188-
}
189-
case TopAbs_VERTEX: {
190-
TopoDS_Vertex* ptr = new TopoDS_Vertex(TopoDS::Vertex(*sh));
191-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Vertex, SWIG_POINTER_OWN | 0 );
192-
if (!resultobj) delete ptr;
193-
break;
194-
}
195-
default:
196-
break;
145+
else {
146+
switch (sh->ShapeType())
147+
{
148+
case TopAbs_COMPOUND: {
149+
TopoDS_Compound* ptr = new TopoDS_Compound(TopoDS::Compound(*sh));
150+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Compound, SWIG_POINTER_OWN | 0);
151+
if (!$result) delete ptr;
152+
break;
153+
}
154+
case TopAbs_COMPSOLID: {
155+
TopoDS_CompSolid* ptr = new TopoDS_CompSolid(TopoDS::CompSolid(*sh));
156+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_CompSolid, SWIG_POINTER_OWN | 0 );
157+
if (!$result) delete ptr;
158+
break;
159+
}
160+
case TopAbs_SOLID: {
161+
TopoDS_Solid* ptr = new TopoDS_Solid(TopoDS::Solid(*sh));
162+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Solid, SWIG_POINTER_OWN | 0 );
163+
if (!$result) delete ptr;
164+
break;
165+
}
166+
case TopAbs_SHELL: {
167+
TopoDS_Shell* ptr = new TopoDS_Shell(TopoDS::Shell(*sh));
168+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Shell, SWIG_POINTER_OWN | 0 );
169+
if (!$result) delete ptr;
170+
break;
171+
}
172+
case TopAbs_FACE: {
173+
TopoDS_Face* ptr = new TopoDS_Face(TopoDS::Face(*sh));
174+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Face, SWIG_POINTER_OWN | 0 );
175+
if (!$result) delete ptr;
176+
break;
177+
}
178+
case TopAbs_WIRE: {
179+
TopoDS_Wire* ptr = new TopoDS_Wire(TopoDS::Wire(*sh));
180+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Wire, SWIG_POINTER_OWN | 0 );
181+
if (!$result) delete ptr;
182+
break;
183+
}
184+
case TopAbs_EDGE: {
185+
TopoDS_Edge* ptr = new TopoDS_Edge(TopoDS::Edge(*sh));
186+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Edge, SWIG_POINTER_OWN | 0 );
187+
if (!$result) delete ptr;
188+
break;
189+
}
190+
case TopAbs_VERTEX: {
191+
TopoDS_Vertex* ptr = new TopoDS_Vertex(TopoDS::Vertex(*sh));
192+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Vertex, SWIG_POINTER_OWN | 0 );
193+
if (!$result) delete ptr;
194+
break;
195+
}
196+
default:
197+
break;
198+
}
197199
}
198-
return resultobj;
199200
}
200201

201202
// Return TopoDS_Shapes by copy, as we could get lifetimes errors
202203
%typemap(out) const TopoDS_Shape& {
203204
TopoDS_Shape* sh = $1;
204205
if (!sh || sh->IsNull()) {
205-
Py_RETURN_NONE;
206+
// Use $result instead of Py_RETURN_NONE to allow SWIG cleanup code to run
207+
$result = Py_None;
208+
Py_INCREF(Py_None);
206209
}
207-
PyObject *resultobj = nullptr;
208-
209-
switch (sh->ShapeType())
210-
{
211-
case TopAbs_COMPOUND: {
212-
TopoDS_Compound* ptr = new TopoDS_Compound(TopoDS::Compound(*sh));
213-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Compound, SWIG_POINTER_OWN | 0);
214-
if (!resultobj) delete ptr;
215-
break;
216-
}
217-
case TopAbs_COMPSOLID: {
218-
TopoDS_CompSolid* ptr = new TopoDS_CompSolid(TopoDS::CompSolid(*sh));
219-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_CompSolid, SWIG_POINTER_OWN | 0 );
220-
if (!resultobj) delete ptr;
221-
break;
222-
}
223-
case TopAbs_SOLID: {
224-
TopoDS_Solid* ptr = new TopoDS_Solid(TopoDS::Solid(*sh));
225-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Solid, SWIG_POINTER_OWN | 0 );
226-
if (!resultobj) delete ptr;
227-
break;
228-
}
229-
case TopAbs_SHELL: {
230-
TopoDS_Shell* ptr = new TopoDS_Shell(TopoDS::Shell(*sh));
231-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Shell, SWIG_POINTER_OWN | 0 );
232-
if (!resultobj) delete ptr;
233-
break;
234-
}
235-
case TopAbs_FACE: {
236-
TopoDS_Face* ptr = new TopoDS_Face(TopoDS::Face(*sh));
237-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Face, SWIG_POINTER_OWN | 0 );
238-
if (!resultobj) delete ptr;
239-
break;
240-
}
241-
case TopAbs_WIRE: {
242-
TopoDS_Wire* ptr = new TopoDS_Wire(TopoDS::Wire(*sh));
243-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Wire, SWIG_POINTER_OWN | 0 );
244-
if (!resultobj) delete ptr;
245-
break;
246-
}
247-
case TopAbs_EDGE: {
248-
TopoDS_Edge* ptr = new TopoDS_Edge(TopoDS::Edge(*sh));
249-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Edge, SWIG_POINTER_OWN | 0 );
250-
if (!resultobj) delete ptr;
251-
break;
252-
}
253-
case TopAbs_VERTEX: {
254-
TopoDS_Vertex* ptr = new TopoDS_Vertex(TopoDS::Vertex(*sh));
255-
resultobj = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Vertex, SWIG_POINTER_OWN | 0 );
256-
if (!resultobj) delete ptr;
257-
break;
258-
}
259-
default:
260-
break;
210+
else {
211+
switch (sh->ShapeType())
212+
{
213+
case TopAbs_COMPOUND: {
214+
TopoDS_Compound* ptr = new TopoDS_Compound(TopoDS::Compound(*sh));
215+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Compound, SWIG_POINTER_OWN | 0);
216+
if (!$result) delete ptr;
217+
break;
218+
}
219+
case TopAbs_COMPSOLID: {
220+
TopoDS_CompSolid* ptr = new TopoDS_CompSolid(TopoDS::CompSolid(*sh));
221+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_CompSolid, SWIG_POINTER_OWN | 0 );
222+
if (!$result) delete ptr;
223+
break;
224+
}
225+
case TopAbs_SOLID: {
226+
TopoDS_Solid* ptr = new TopoDS_Solid(TopoDS::Solid(*sh));
227+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Solid, SWIG_POINTER_OWN | 0 );
228+
if (!$result) delete ptr;
229+
break;
230+
}
231+
case TopAbs_SHELL: {
232+
TopoDS_Shell* ptr = new TopoDS_Shell(TopoDS::Shell(*sh));
233+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Shell, SWIG_POINTER_OWN | 0 );
234+
if (!$result) delete ptr;
235+
break;
236+
}
237+
case TopAbs_FACE: {
238+
TopoDS_Face* ptr = new TopoDS_Face(TopoDS::Face(*sh));
239+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Face, SWIG_POINTER_OWN | 0 );
240+
if (!$result) delete ptr;
241+
break;
242+
}
243+
case TopAbs_WIRE: {
244+
TopoDS_Wire* ptr = new TopoDS_Wire(TopoDS::Wire(*sh));
245+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Wire, SWIG_POINTER_OWN | 0 );
246+
if (!$result) delete ptr;
247+
break;
248+
}
249+
case TopAbs_EDGE: {
250+
TopoDS_Edge* ptr = new TopoDS_Edge(TopoDS::Edge(*sh));
251+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Edge, SWIG_POINTER_OWN | 0 );
252+
if (!$result) delete ptr;
253+
break;
254+
}
255+
case TopAbs_VERTEX: {
256+
TopoDS_Vertex* ptr = new TopoDS_Vertex(TopoDS::Vertex(*sh));
257+
$result = SWIG_NewPointerObj(ptr, SWIGTYPE_p_TopoDS_Vertex, SWIG_POINTER_OWN | 0 );
258+
if (!$result) delete ptr;
259+
break;
260+
}
261+
default:
262+
break;
263+
}
261264
}
262-
return resultobj;
263265
}
264266

265267

0 commit comments

Comments
 (0)