In your structure at (presumably) offset 4, there is a list of 10 bytes one by one containing letters that make "Hello"; Thus (data + 4) is a pointer to char and must be encoded accordingly (i.e. char * ).
However, after these 10 bytes, enter a few bytes that make the buffer address somewhere, i.e. these bytes are "char *" (you defined them like that), so the data offset + is a pointer to a char -pointer or char ** .
What is probably confusing is that both
strcpy (test.arr, "Hello");
strcpy (test.str, "World!");
Job.
This is a confusing (but useful C / C ++ function). The name of the array, when used in a place that requires a pointer to the type of the element of the array, will be processed by the compiler as if it were a pointer to the first element of the array.
So test.str explicitly a pointer to a char (because you defined it that way). test.arr can be used as a pointer to the first element of the test, if the situation prompts this.
When you write strcpy(test.arr, "Hello "); what do you think the compiler means strcpy(&test.arr[0], "Hello ");
source share