Thread overview
Memory management by interfacing C/C++
Apr 27, 2019
Ferhat Kurtulmuş
Apr 28, 2019
Paul Backus
Apr 28, 2019
Ferhat Kurtulmuş
Apr 29, 2019
Paul Backus
Apr 29, 2019
Ferhat Kurtulmuş
Apr 29, 2019
9il
Apr 29, 2019
Ferhat Kurtulmuş
April 27, 2019
Hi,

I am wrapping some C++ code for my personal project (opencvd), and I am creating so many array pointers at cpp side and containing them in structs. I want to learn if I am leaking memory like crazy, although I am not facing crashes so far. Is GC of D handling things for me? Here is an example:

```
//declaration in d
struct IntVector {
    int* val;
    int length;
}

// in cpp
typedef struct IntVector {
    int* val;
    int length;
} IntVector;

// cpp function returning a struct containing an array pointer allocated with "new" op.
IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){
    std::vector<int> iv;
    sd->getLeadingEdgeList(iv);

    int *cintv = new int[iv.size()]; // I don't call delete anywhere?

    for(size_t i=0; i < iv.size(); i++){
        cintv[i] = iv[i];
    }
    IntVector ret = {cintv, (int)iv.size()};
    return ret;
};

// call extern c function in d:
extern (C) IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2d sd);

int[] getLeadingEdgeList(){
    IntVector intv = Subdiv2D_GetLeadingEdgeList(this);
    int[] ret = intv.val[0..intv.length]; // just D magic. Still no delete anywhere!
    return ret;
}
```

The question is now: what will happen to "int *cintv" which is allocated with new operator in cpp code? I have many code similar in the project, but I have not encounter any problem so far even in looped video processings. Is GC of D doing deallocation automagically?
https://github.com/aferust/opencvd
April 28, 2019
On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş wrote:
> Hi,
>
> I am wrapping some C++ code for my personal project (opencvd), and I am creating so many array pointers at cpp side and containing them in structs. I want to learn if I am leaking memory like crazy, although I am not facing crashes so far. Is GC of D handling things for me? Here is an example:
>
> [...]
>
> The question is now: what will happen to "int *cintv" which is allocated with new operator in cpp code? I have many code similar in the project, but I have not encounter any problem so far even in looped video processings. Is GC of D doing deallocation automagically?
> https://github.com/aferust/opencvd

D's GC only collects memory allocated with D's `new` operator. Memory allocated by C++'s `new` operator must be freed by C++'s `delete` operator.
April 28, 2019
On Sunday, 28 April 2019 at 03:54:17 UTC, Paul Backus wrote:
> On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş wrote:
>> Hi,
>>
>> I am wrapping some C++ code for my personal project (opencvd), and I am creating so many array pointers at cpp side and containing them in structs. I want to learn if I am leaking memory like crazy, although I am not facing crashes so far. Is GC of D handling things for me? Here is an example:
>>
>> [...]
>>
>> The question is now: what will happen to "int *cintv" which is allocated with new operator in cpp code? I have many code similar in the project, but I have not encounter any problem so far even in looped video processings. Is GC of D doing deallocation automagically?
>> https://github.com/aferust/opencvd
>
> D's GC only collects memory allocated with D's `new` operator. Memory allocated by C++'s `new` operator must be freed by C++'s `delete` operator.

You are right. I am rewriting the things using mallocs, and will use core.stdc.stdlib.free on d side. I am not sure if I can use core.stdc.stdlib.free to destroy arrays allocated with new op.
April 29, 2019
On Sunday, 28 April 2019 at 23:10:24 UTC, Ferhat Kurtulmuş wrote:
> You are right. I am rewriting the things using mallocs, and will use core.stdc.stdlib.free on d side. I am not sure if I can use core.stdc.stdlib.free to destroy arrays allocated with new op.

core.stdc.stdlib.free is (as the name suggests) the standard C `free` function. As such, it can only be used to free memory allocated by the standard C functions `malloc`, `calloc`, and `realloc`. This is the same in D as it is in C and C++.
April 29, 2019
On Monday, 29 April 2019 at 00:53:34 UTC, Paul Backus wrote:
> On Sunday, 28 April 2019 at 23:10:24 UTC, Ferhat Kurtulmuş wrote:
>> You are right. I am rewriting the things using mallocs, and will use core.stdc.stdlib.free on d side. I am not sure if I can use core.stdc.stdlib.free to destroy arrays allocated with new op.
>
> core.stdc.stdlib.free is (as the name suggests) the standard C `free` function. As such, it can only be used to free memory allocated by the standard C functions `malloc`, `calloc`, and `realloc`. This is the same in D as it is in C and C++.

Thank you. It is now like:

/* c/cpp side */
extern (C) void deleteArr(void* arr);

void deleteArr(void* arr){
    delete[] arr;
}

struct IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){
    std::vector<int> iv;
    sd->getLeadingEdgeList(iv);
    int *cintv = new int[iv.size()];
    for(size_t i=0; i < iv.size(); i++){
        cintv[i] = iv[i];
    }
    IntVector ret = {cintv, (int)iv.size()};
    return ret;
};

/* c/cpp side */

...
int[] getLeadingEdgeList(){ // d function
    IntVector intv = Subdiv2D_GetLeadingEdgeList(this);
    int[] ret = intv.val[0..intv.length].dup;
    deleteArr(intv.val);
    return ret;
}
...

April 29, 2019
On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş wrote:
> Hi,
>
> I am wrapping some C++ code for my personal project (opencvd), and I am creating so many array pointers at cpp side and containing them in structs. I want to learn if I am leaking memory like crazy, although I am not facing crashes so far. Is GC of D handling things for me? Here is an example:
>
> ```
> //declaration in d
> struct IntVector {
>     int* val;
>     int length;
> }
>
> // in cpp
> typedef struct IntVector {
>     int* val;
>     int length;
> } IntVector;
>
> // cpp function returning a struct containing an array pointer allocated with "new" op.
> IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){
>     std::vector<int> iv;
>     sd->getLeadingEdgeList(iv);
>
>     int *cintv = new int[iv.size()]; // I don't call delete anywhere?
>
>     for(size_t i=0; i < iv.size(); i++){
>         cintv[i] = iv[i];
>     }
>     IntVector ret = {cintv, (int)iv.size()};
>     return ret;
> };
>
> // call extern c function in d:
> extern (C) IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2d sd);
>
> int[] getLeadingEdgeList(){
>     IntVector intv = Subdiv2D_GetLeadingEdgeList(this);
>     int[] ret = intv.val[0..intv.length]; // just D magic. Still no delete anywhere!
>     return ret;
> }
> ```
>
> The question is now: what will happen to "int *cintv" which is allocated with new operator in cpp code? I have many code similar in the project, but I have not encounter any problem so far even in looped video processings. Is GC of D doing deallocation automagically?
> https://github.com/aferust/opencvd

Hello Ferhat,

You can use RCArray!T or Slice!(RCI!T) [1, 2] as common thread safe @nogc types for D and C++ code.
See also integration C++ example [3] and C++ headers [4].


RCArray (fixed length)
[1] http://mir-algorithm.libmir.org/mir_rc_array.html
RCSlice (allows to get subslices)
[2] http://mir-algorithm.libmir.org/mir_ndslice_allocation.html#rcslice
C++ integration example
[3] https://github.com/libmir/mir-algorithm/tree/master/cpp_example
C++ headers
[4] https://github.com/libmir/mir-algorithm/tree/master/include/mir

April 29, 2019
On Monday, 29 April 2019 at 14:38:54 UTC, 9il wrote:
> On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş wrote:
>> [...]
>
> Hello Ferhat,
>
> You can use RCArray!T or Slice!(RCI!T) [1, 2] as common thread safe @nogc types for D and C++ code.
> See also integration C++ example [3] and C++ headers [4].
>
>
> RCArray (fixed length)
> [1] http://mir-algorithm.libmir.org/mir_rc_array.html
> RCSlice (allows to get subslices)
> [2] http://mir-algorithm.libmir.org/mir_ndslice_allocation.html#rcslice
> C++ integration example
> [3] https://github.com/libmir/mir-algorithm/tree/master/cpp_example
> C++ headers
> [4] https://github.com/libmir/mir-algorithm/tree/master/include/mir
An opencv d binding using ndslice substituting cv::Mat would be useful like opencv-python using numpy. However, I started opencvd about a month ago, and I am very new to d. For now, I am the only contributor with zero mir.ndslice experience. When I gain more experience with ndslice, I would try it as substitution for cv::Mat. Thank you for links 9il. I will take a look at them.