I am attempting to free a heap allocated Ada tagged record from cpp. I have used the code AdacoreU as a starting place.
I receive the following error when running the code below.
20
double free or corruption (out)
raised PROGRAM_ERROR : unhandled signal
Am I overthinking things? Do I need an Ada based deallocation mechanism.
What is my real end goal? I would like to use dynamic libraries to create a plugin infrastructure where each library is its own factory for a given type. Something along the lines of boost dll but with ada based dynamic libraries.
Modified Code below:
main.cpp
1 #include <iostream>
2 #include "animal.h"
3
4 extern "C" {
5 void adainit (void);
6 void adafinal (void);
7 Animal* new_animal();
8 void del_animal(Animal *);
9 }
10
11 int main(void) {
12 adainit();
13 Animal* A = new_animal();
14 std::cout << A->age() << std::endl;
15 //delete A;
16 del_animal(A);
17 adafinal();
18 return 0;
19 };
alib.ads
1
2 with Interfaces.C;
3
4 package ALib is
5
6 type Animal is tagged record
7 The_Age : Interfaces.C.int;
8 end record;
9 pragma Convention (CPP, Animal);
10
11 type Animal_Class_Access is access Animal'Class;
12
13 function New_Animal return access Animal'Class;
14 pragma Export(CPP, New_Animal);
15
16 procedure Del_Animal (this : in out Animal_Class_Access);
17 pragma Export(CPP, Del_Animal);
18
19 function Age(X : Animal) return Interfaces.C.int;
20 pragma Export(CPP, Age);
21
22 end ALib;
alib.adb
1 with ada.unchecked_deallocation;
2
3 package body ALib is
4
5 function New_Animal
6 return access Animal'Class is
7 begin
8 return new Animal'(The_Age => 20);
9 end New_Animal;
10
11
12 procedure Del_Animal (this : in out Animal_Class_Access) is
13 procedure Free is new ada.unchecked_deallocation(Animal'Class, Animal_Class_Access);
14 begin
15 Free(this);
16 --null;
17 end Del_Animal;
18
19 function Age(X : Animal)
20 return Interfaces.C.int is
21 begin
22 return X.The_Age;
23 end Age;
24
25 end ALib;
~
other resources used as a starting point
3.11.3.5 Interfacing with C++ at the Class Level
What have I attempted:
What did I expect:
I expected to clean up Ada heap objects from Ada.
The problem is with the in out
parameter to Del_Animal
and its mapping to the C world.
Your intention with Del_Animal
is that it should behave like Ada.Unchecked_Deallocation
, in other words that the parameter is set to null
(or 0
!) after the call, but that means that what you have to pass is the address of the actual.
That is,
void del_animal(Animal**);
called as
del_animal(&A);
See ARM B3(68).