Note that there are some explanatory texts on larger screens.

plurals
  1. POC char array as pointers
    primarykey
    data
    text
    <p>I want to understand:</p> <ul> <li>why it happens that sometimes a <code>char[1]</code> in C is used as <code>char*</code> (why doing this?) and</li> <li>how the internals works (what's going on)</li> </ul> <p>Giving following sample program:</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;string.h&gt; struct test_struct { char *a; char b[1]; } __attribute__((packed)); ; int main() { char *testp; struct test_struct test_s; testp = NULL; memset(&amp;test_s, 0, sizeof(struct test_struct)); printf("sizeof(test_struct) is: %lx\n", sizeof(struct test_struct)); printf("testp at: %p\n", &amp;testp); printf("testp is: %p\n", testp); printf("test_s.a at: %p\n", &amp;test_s.a); printf("test_s.a is: %p\n", test_s.a); printf("test_s.b at: %p\n", &amp;test_s.b); printf("test_s.b is: %p\n", test_s.b); printf("sizeof(test_s.b): %lx \n", sizeof(test_s.b)); printf("real sizeof(test_s.b): %lx \n", ((void *)(&amp;test_s.b) - (void *)(&amp;test_s.a)) ); return 0; } </code></pre> <p>I get the following output (OS X, 64bit):</p> <pre><code>sizeof(test_struct) is: 9 testp at: 0x7fff62211a98 testp is: 0x0 test_s.a at: 0x7fff62211a88 test_s.a is: 0x0 test_s.b at: 0x7fff62211a90 test_s.b is: 0x7fff62211a90 sizeof(test_s.b): 1 real sizeof(test_s.b): 8 </code></pre> <p>Looking at the memory addresses, one can see that even the struct is 9 bytes large, 16 bytes were allocated which seems to be caused by <code>char b[1]</code>. But I'm not sure if those extra bytes were allocated due to optimization/mem alignment reasons, or if this has to do with C's internal treatment of char arrays.</p> <p>A real world example can be seen in <code>&lt;fts.h&gt;</code>:</p> <p>`man 3 fts` shows the struct member `fts_name` as:</p> <pre><code> char *fts_name; /* file name */ </code></pre> <p>while /usr/include/fts.h defines the member as:</p> <pre><code> char fts_name[1]; /* file name */ </code></pre> <p>In the end, <code>fts_name</code> can really be used as a pointer to a C-string. For example, printing to stdout with <code>printf("%s", ent-&gt;fts_name)</code> works.</p> <p>So if a <code>char[1]</code> is really one byte large, it couldn't be used as a memory pointer on my 64bit machine. On the other hand, treating this as a full blown <code>char *</code> doesn't work either, as can be seen with the <code>test_s.b is</code> output above, which should show a NULL pointer then...</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload