www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Returning dynamic array from the function?

reply SuperPrower <superprower somedomain.org> writes:
I have a function that produces dynamic array of strings. I would 
like to return this array from this function. I understand that 
dynamic arrays are of reference type, and thus if I try to return 
array variable, I will actually return a pointer to the first 
element of the array on the heap. Problem is, when I return 
dynamic array and try to print it outside of the function, I see 
garbage in a first few elements.

My humble experience with languages like C++ doesn't really help 
with understanding how Garbage Collector (if it's because of it, 
because if I understand correctly, I can imagine memory being 
de-allocated because we get out of scope of local variable that 
points to the array, thus there are no more pointers to this 
memory, thus it gets de-allocated, but we still return reference 
to this memory, so GC shouldn't really free it?) can cause this - 
can anyone please explain me what's exactly going on and what 
would be the proper way to return dynamic array from the 
function? Thanks in advance.
Sep 08 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 08/09/2018 9:34 PM, SuperPrower wrote:
 I have a function that produces dynamic array of strings. I would like 
 to return this array from this function. I understand that dynamic 
 arrays are of reference type, and thus if I try to return array 
 variable, I will actually return a pointer to the first element of the 
 array on the heap. Problem is, when I return dynamic array and try to 
 print it outside of the function, I see garbage in a first few elements.
 
 My humble experience with languages like C++ doesn't really help with 
 understanding how Garbage Collector (if it's because of it, because if I 
 understand correctly, I can imagine memory being de-allocated because we 
 get out of scope of local variable that points to the array, thus there 
 are no more pointers to this memory, thus it gets de-allocated, but we 
 still return reference to this memory, so GC shouldn't really free it?) 
 can cause this - can anyone please explain me what's exactly going on 
 and what would be the proper way to return dynamic array from the 
 function? Thanks in advance.
We're going to need to see a minified version of the code to see what you're doing.
Sep 08 2018
parent reply SuperPrower <superprower somedomain.org> writes:
On Saturday, 8 September 2018 at 09:36:21 UTC, rikki cattermole 
wrote:
 We're going to need to see a minified version of the code to 
 see what you're doing.
Sure, here it is: ``` auto getBoards() { string[] boardList; auto url = baseUrl ~ "/api/v2/boards"; auto http = HTTP(url); http.method = HTTP.Method.get; http.onReceive = (ubyte[] data) { auto content = cast(string) data[]; boardList = strip(content, "[", "]").split(","); foreach (ref b; boardList) { b = strip(b, `"`); } return data.length; }; http.perform(); writeln(boardList); return boardList; } ``` This is a member function of some class. It doesn't really have any fields, so I left if out. In it, I use curl library to getch some data and split it. Next, I try to use this function to get this list: ``` Fetcher fetcher = new Fetcher; auto boards = fetcher.getBoards(); writeln(boards); ``` I printed array twice: inside the function and after return. Here is the output: ``` ["a", "burg", "cyb", "d", "lain", "mu", "new", "tech", "test", "u", "v", "all"] [x"F9"c, x"FA 01 00 00"c, "\0\0\0", "d", "lain", "mu", "new", "tech", "test", "u", "v", "all"] ``` As you can see, when outside of the funtion, first few elements of the array contain garbage. I would like to know both why this happens and how do I avoid it (i.e. what is the correct way of returning dynamic array).
Sep 08 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 08/09/2018 9:46 PM, SuperPrower wrote:
 On Saturday, 8 September 2018 at 09:36:21 UTC, rikki cattermole wrote:
 We're going to need to see a minified version of the code to see what 
 you're doing.
Sure, here it is: ``` auto getBoards() {     string[] boardList;     auto url = baseUrl ~ "/api/v2/boards";     auto http = HTTP(url);     http.method = HTTP.Method.get;     http.onReceive = (ubyte[] data) {         auto content = cast(string) data[];
auto content = cast(string)(data.dup);
          boardList = strip(content, "[", "]").split(",");
          foreach (ref b; boardList) {
              b = strip(b, `"`);
          }
 
          return data.length;
      };
 
      http.perform();
      writeln(boardList);
      return boardList;
 }
 ```
 
 This is a member function of some class. It doesn't really have any 
 fields, so I left if out. In it, I use curl library to getch some data 
 and split it. Next, I try to use this function to get this list:
 
 ```
 Fetcher fetcher = new Fetcher;
 
 auto boards = fetcher.getBoards();
 writeln(boards);
 ```
 I printed array twice: inside the function and after return. Here is the 
 output:
 ```
 ["a", "burg", "cyb", "d", "lain", "mu", "new", "tech", "test", "u", "v", 
 "all"]
 [x"F9"c, x"FA 01 00 00"c, "\0\0\0", "d", "lain", "mu", "new", "tech", 
 "test", "u", "v", "all"]
 ```
 
 As you can see, when outside of the funtion, first few elements of the 
 array contain garbage. I would like to know both why this happens and 
 how do I avoid it (i.e. what is the correct way of returning dynamic 
 array).
onReceive: "The event handler that receives incoming data. Be sure to copy the incoming ubyte[] since it is not guaranteed to be valid after the callback returns." It could be a buffer on the stack, either way, .dup it before you cast.
Sep 08 2018
parent reply SuperPrower <superprower somedomain.org> writes:
On Saturday, 8 September 2018 at 10:05:31 UTC, rikki cattermole 
wrote:
 onReceive:
 "The event handler that receives incoming data. Be sure to copy 
 the incoming ubyte[] since it is not guaranteed to be valid 
 after the callback returns."

 It could be a buffer on the stack, either way, .dup it before 
 you cast.
Yeah, it worked, thank you. I knew it was something trivial like that. It appears I slightly misunderstood by this paragraph https://dlang.org/spec/arrays.html#array-copying - I missed that slice operator is supposed to be on the left-side rather than right (I thought adding `[]` to the `data` would do the trick). Also, is this me and my bad English, or first comment in code in this paragraph (linked above, not in the discussion) is supposed to be something different? Shouldn't it be reference?
Sep 08 2018
parent rjframe <dlang ryanjframe.com> writes:
On Sat, 08 Sep 2018 10:22:38 +0000, SuperPrower wrote:

 Also, is this me and my bad English, or first comment in code in this
 paragraph (linked above, not in the discussion) is supposed to be
 something different? Shouldn't it be reference?
Static arrays are value types, so the values are copied (see section 12.1.2 on that page). That said, static arrays do make that example a bit strange.
Sep 08 2018