Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You ask:</p> <blockquote> <p>Is there anything I should know about using strtok on a malloced string?</p> </blockquote> <p>There are a number of things to be aware of. First, <code>strtok()</code> modifies the string as it processes it, inserting nulls (<code>'\0'</code>) where the delimiters are found. This is not a problem with allocated memory (that's modifiable!); it is a problem if you try passing a constant string to <code>strtok()</code>.</p> <p>Second, you must have as many calls to <code>free()</code> as you do to <code>malloc()</code> and <code>calloc()</code> (but <code>realloc()</code> can mess with the counting).</p> <blockquote> <p>In my code I have (in general terms)</p> <pre><code> char* line=getline(); Parse(dest,line); free(line); </code></pre> </blockquote> <p>Unless <code>Parse()</code> allocates the space it keeps, you cannot use the <code>dest</code> structure (or, more precisely, the pointers into the line within the <code>dest</code> structure) after the call to <code>free()</code>. The <code>free()</code> releases the space that was allocated by <code>getline()</code> and any use of the pointers after that yields undefined behaviour. Note that undefined behaviour includes the option of 'appearing to work, but only by coincidence'.</p> <blockquote> <p>where getline() is a function that returns a char * to some malloced memory, and Parse(dest, line) is a function that does parsing online, storing the results in dest (which has been partially filled earlier, from other information).</p> <p>Parse() calls strtok() a a variable number of times on line, and does some validation. Each token (a pointer to what is returned by strtok()) is put into a queue 'til I know how many I have.</p> </blockquote> <p>Note that the pointers returned by <code>strtok()</code> are all pointers into the single chunk of space allocated by <code>getline()</code>. You have not described any extra memory allocation.</p> <blockquote> <p>They are then copied onto a malloc'd char** in dest.</p> </blockquote> <p>This sounds as if you copy the pointers from <code>strtok()</code> into an array of pointers, but you do not attend to copying the data that those pointers are pointing at.</p> <blockquote> <p>Now free(line) and a function that free's each part of the char*[] in dest, both come up on valgrind as:</p> <pre><code>"Address 0x5179450 is 8 bytes inside a block of size 38 free'd" </code></pre> <p>or something similar.</p> </blockquote> <p>The first <code>free()</code> of the '<code>char *[]</code>' part of <code>dest</code> probably has a pointer to <code>line</code> and therefore frees the whole block of memory. All the subsequent frees on the parts of <code>dest</code> are trying to free an address not returned by <code>malloc()</code>, and <code>valgrind</code> is trying to tell you that. The <code>free(line)</code> operation then fails because the first <code>free()</code> of the pointers in <code>dest</code> already freed that space.</p> <blockquote> <p>I'm considering refactoring my code [to] store a copy of them [...].</p> </blockquote> <p>The refactoring proposed is probably sensible; the function <code>strdup()</code> already mentioned by others will do the job neatly and reliably.</p> <p>Note that after refactoring, you will still need to release line, but you will not release any of the pointers returned by <code>strtok()</code>. They are just pointers into the space managed by (identified by) <code>line</code> and will all be released when you release <code>line</code>.</p> <p>Note that you will need to free each of the separately allocated (<code>strdup()</code>'d) strings as well as the array of character pointers that are accessed via <code>dest</code>.</p> <p>Alternatively, do not free line immediately after calling <code>Parse()</code>. Have <code>dest</code> record the allocated pointer (<code>line</code>) and free that when it frees the array of pointers. You still do not release the pointers returned by <code>strtok()</code>, though.</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. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      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