Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>char *p = "String"; </code></pre> <p>This is legal, but it really should be:</p> <pre><code>const char *p = "String"; </code></pre> <p>so you don't accidentally try to modify the array.</p> <p>What array, you ask? Any string literal corresponds to a statically allocated array of size <code>LEN+1</code>, where <code>LEN</code> is the length of the literal. So in this case, there's an <em>anonymous</em> array of type <code>char[7]</code> that exists during the entire execution of your program, containing the values</p> <pre><code>`{ 'S', 't', 'r', 'i', 'n', 'g', '\0' }`. </code></pre> <p>The initializer for <code>p</code> causes it to point to the first element of that array, which contains the <code>'S'</code>. And since the array was not allocated by a call to <code>malloc()</code> (or <code>calloc()</code>, or <code>realloc()</code>), you <em>must not</em> attempt to <code>free()</code> it.</p> <p>Given <code>p</code>, you can't directly determine the size of the array (since <code>p</code> points to its first element, not to the array as a whole). You can compute <code>strlen(p) + 1</code>, which is <em>probably</em> the same as the allocated size -- but if the string literal were <code>"foo\0bar"</code>, then it would be 8 bytes long, but <code>strlen</code> would stop at the first null character and return <code>3</code>. So if you need to be able to determine the size of the array, don't discard that information by assigning its address to a pointer.</p> <p>Now if you had instead written:</p> <pre><code>char arr[] = "String"; </code></pre> <p>the initializer would <em>copy</em> the contents of the string literal into the array <code>arr</code>, and the size of <code>arr</code> would be determined by the compiler from the size of the initializer. Again, you must not attempt to call <code>free()</code> on this array (or rather, on a pointer to its first element), since it wasn't allocated with <code>malloc()</code>. But you can easily determine its size via <code>sizeof arr</code>, which will yield <code>7</code>. (<code>sizeof p</code> would give you the size of a pointer, not of the array it points to.)</p> <p>Finally, if you used <code>malloc()</code> to allocate an array:</p> <pre><code>#define message "String" char *p = malloc(sizeof message + 1); if (p == NULL) { fprintf(stderr, "malloc failed\n"); exit(EXIT_FAILURE); } strcpy(p, message); </code></pre> <p>you still can't use <code>p</code> (which is just a pointer to a single character) to determine the size of the allocated array -- but <code>free()</code> is able to figure it out. How? The language doesn't say, but any implementation will keep extra bookkeeping information behind the scenes to let <code>free()</code> do the right thing.</p> <p>Note that the implementation doesn't necessarily remember the size you requested. A call to <code>malloc(7)</code> might actually allocate, say, 16 bytes, and the only information <code>free</code> needs is the base address and the actual allocated size.</p> <p>But since you wrote the call to <code>malloc</code>, if you need to remember the allocated size, just save it somewhere:</p> <pre><code>// ... const size_t allocated_bytes = sizeof message + 1; char *p = malloc(allocated_bytes); // ... </code></pre> <p>If you have a declared array object, you can use <code>sizeof</code> to determine its size. Arrays are usually manipulated using pointers, which do not retain the size of the array; you have to keep track of that yourself. <code>malloc()</code> and friends do maintain some size information behind the scenes, but only for the purpose of letting <code>free()</code> work correctly; you (probably) can't access that information yourself. If you need to keep track of the size of an allocated array, you have to do it yourself.</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.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    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