www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Memory management by interfacing C/C++

reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
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
Apr 27 2019
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
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.
Apr 27 2019
parent reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
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.
Apr 28 2019
parent reply Paul Backus <snarwin gmail.com> writes:
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++.
Apr 28 2019
parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
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; } ...
Apr 29 2019
prev sibling parent reply 9il <ilyayaroshenko gmail.com> writes:
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
Apr 29 2019
parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
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.
Apr 29 2019