The confusion about static and dynamic arrays in C

typedef struct mystruct{ int a; char arr[10]; char *str; }mystruct; void f(void *data, int offset){ char *s = (char *)(data + offset); printf("%s", s); } void g(void *data, int offset){ char *s = *(char **)(data+offset); printf("%s", s); } int main(){ mystruct test; test.a = 2; test.str = malloc(100); strcpy(test.arr, "Hello "); strcpy(test.str, "World!"); f(&test, offsetof(mystruct,arr)); g(&test, offsetof(mystruct,str)); return 0; } 

I am wondering why I need two different ways to print lines. In f function, what actually indicates (data + offset)? Doesn't this point to arr , which is the char pointer for the first element of the string? But in the g function (data + offset) points to a char pointer. So, why use two different approaches to accomplish the same task?

+4
source share
5 answers

In both cases, data+offset indicates a member of the structure.

But consider the structure structure. It consists of

 +-----+--------------------------------------------+ | a | sizeof(int) probably 4 or 8 bytes | +-----+--------------------------------------------+ | possible padding of unknown size (probably zero) | +-----+--------------------------------------------+ | arr | 10 bytes | +-----+--------------------------------------------+ | possible padding of unknown size (maybe 2 bytes) | +-----+--------------------------------------------+ | str | sizeof(char*) probably 4 or 8 bytes | +-----+--------------------------------------------+ 

and elsewhere in the memory is a block of 100 bytes allocated with malloc .

Note that the data for test.arr stored in the memory allocated for test , but the thing stored in test for test.str is the address of another memory block.

+3
source

You must provide the compiler with information about the type of pointer that you have in the f and g functions, you cannot do point arithmetic on void pointers.

Insert data into char pointer and printf will work

 void f(void *data, int offset){ char *s = (char *)(( char*)data + offset); printf("%s", s); } void g(void *data, int offset){ char *s = *(char **)((char*)data+offset); printf("%s", s); } 
+1
source

In f function, what does (data + offset) actually indicate? This is not pointing to arr , which is the char pointer for the first element of the string?

This is your main source of confusion. arr not a pointer, it is an array. Arrays are not pointers. Meanwhile, str is a pointer. Arrays and pointers are two completely different things. They have practically nothing in common. And that is why you have to work with them differently.

Arrays and pointers can behave very similarly in so-called value contexts (i.e. when used as rvalues), but this is purely superficial similarity. They immediately reveal their main differences in the so-called object contexts (i.e. when used as lvalues). In your specific example, your membership access code is an example of the context of the object, so you should carefully observe the difference between arr and str .

The question of the differences between arrays and pointers has been considered many times. I see no reason to repeat it here. Just do a search on the "difference of array pointers" on SO. Or read the basic FAQ

http://c-faq.com/aryptr/index.html

PS Also note that C does not support pointer arithmetic on void * pointers. All your expressions (data + offset) not allowed. What you wanted to do is really ((char *) data + offset) . Converting data from void * to char * is required in order to be able to perform point arithmetic with byte offsets.

+1
source

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 ");

0
source

In function f, what (data + offset) actually points to?

It points to the member 'arr' of the structure object (if you assume GCC semantics for void pointer arithmetic).

Does this point to arr, which is a char pointer to the first element of the string?

arr is a char array, not a char pointer.

But the char pointer is also specified in the g (data + offset) function.

In this case, it points to a char pointer, yes.

So, why use two different approaches to accomplish the same task?

Pointers have two different things: from one to a char pointer (which itself points to a char array), and the other to a char array. In the first case, there is another level of indirection.

0
source

Source: https://habr.com/ru/post/1485844/


All Articles