Append to dynamic array that was allocated via calloc

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jul 25 06:39:55 PDT 2017


On 7/25/17 8:40 AM, John Burton wrote:
> I can create a "slice" using non-gc allocated memory.
> 
>          int* ptr = cast(int*)calloc(int.sizeof, 10);
>          int[] data = ptr[0..10];
> 
> If I don't want a memory leak I have to call free(ptr) somewhere as it 
> won't be GC collected when data or ptr go out of scope. I presume there 
> is nothing wrong with doing the above, other than perhaps there being 
> better ways (and the memory leak if not free'd)
> 
> If I then write this :-
> 
>          data ~= 1;
> 
> What happens? It seems to successfully append an extra value to the 
> array. It appears to "work" when I try it in my compiler but I don't 
> understand how. Will this be trying to write beyond the memory I calloc'ed?

What happens is the runtime detects that data is NOT pointing at an 
appendable GC-allocated block.

So it reallocates the whole block in the GC, and appends your element.

The original pointer is lost from data, and leaked (assuming you aren't 
manually freeing ptr somewhere).

I'd recommend using std.container.Array[1], which should do the right 
thing with malloc'd memory, and give you the nice operators such as ~=.

Or you have to resort to C calls for everything, if you don't want to 
deal with that.

Optionally, if you have a defined lifetime for this array in a scope, 
you can do this:

int *ptr = ...; // your calloc call
scope(exit) free(ptr); // ensure it is freed. Make SURE you don't change 
ptr inside the function.

Now you can use ~= on data, and it should still free the ptr at the end 
of the scope/function.

-Steve

[1] http://dlang.org/phobos/std_container_array.html#.Array


More information about the Digitalmars-d-learn mailing list