Pointers to Dynamic Arrays

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 16 20:07:24 PDT 2015


On Monday, 17 August 2015 at 02:45:22 UTC, Brandon Ragland wrote:
> Since Dynamic Arrays / Slices are a D feature, using pointers 
> to these has me a bit confused...

Short answer: pointers to slices are usually a mistake, you 
probably don't actually want it, but rather should be using a 
regular slice instead.

> string c2s(int* pos, char[]* file, int l){
> 	char[] s;
> 	for(int i = 0; i < l; i++){
> 		s ~= file[(*pos + i)];

Here, for example, you've accidentally escaped slice land and are 
unto unchecked pointer arithmetic.

Since file is declared char[]* instead of char[], indexing it 
works C style: it at the index as an offset from the base char[].

In other words, it works more as if you wrote `char** file` in C. 
(still not identically, a D slice is different than a C char*, 
but same idea).

The above will only really work fine for index 0. Anything else 
would be a wild pointer. If this didn't crash on you, you just 
got kinda lucky with the index.

The append compiles because dereferencing a `char[]*` yields a 
`char[]`, which D can append normally.


> Now what is especially confusing about this, is that the above 
> seems to works fine, while this does not:
>
> if(file[(*pos + i)] == '}'){

This errors for the same reason the top one succeeded: what's 
pointed to by a char[]* is char[], not char. So you are trying to 
compare a string on the left hand side to an individual character 
on the right hand side.

In other words, what your error message told :)

> I can no longer assume that using the dynamic array pointer 
> works anything like a standard pointer to an array, or a 
> pointer to a dynamic array.

char[] in D is like:

struct char_array {
     size_t length;
     char* ptr;
}

in C. Since there's already a pointer in there, you typically 
don't want the address of this struct, you just want to pass it 
right down by value and let the pointer be copied (it still 
points to the same actual data).

BTW you can access those .length and .ptr values in D:

char[] slice;
char* a = slice.ptr; // works

The only time you'd actually want a char[]* in D is if you need 
to write back to the original *variable* once you append or 
shrink it. (The contents are fine, they can be modified through 
the slice with no special effort.)


Bottom line again is char[] in D is like char* in C. So char[]* 
in D is more like char** in C.




More information about the Digitalmars-d-learn mailing list