Thread overview
Returning dynamic array from the function?
Sep 08, 2018
SuperPrower
Sep 08, 2018
rikki cattermole
Sep 08, 2018
SuperPrower
Sep 08, 2018
rikki cattermole
Sep 08, 2018
SuperPrower
Sep 08, 2018
rjframe
September 08, 2018
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.
September 08, 2018
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.
September 08, 2018
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).
September 08, 2018
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.
September 08, 2018
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?
September 08, 2018
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.