title: Freeing allocated memory conditionally within a macro in C
body: <p>I have a function that reads a csv file and then updates a <code>struct</code> with it's parameters.
  I wanted to be able to cycle through a structs elements, so I turned to macros. The output of parsing the csv files is a 2 dimensional array of strings for rows and columns of the file. To convert the strings to their respective data type (currently the structs only have <code>int</code> and <code>char*</code>) I used a conversion macro within the macro used to cycle through the struct.</p>
  
  <pre><code>CVT_INT atoi(str)
  CVT_STR str
  </code></pre>
  
  <p>However, when it comes to freeing the memory allocated by parsing the csv file, it gets tricky if in the file the strings are not grouped together at the start or end.</p>
  
  <pre><code>csv[row][col]
  string|string|int|string|int
  string|string|int|string|int
  ...
  
  for(int row = 0; row &lt; number_of_rows; row++)
      for(int col = 2; col &lt; number_of_cols; col++)
          free(csv[row][col]) // frees string when row[i][3]
  </code></pre>
  
  <p>I could just make sure all the strings are at the beginning of the structure, but I want it to be dynamic and I don't want to have to think about making sure the data types are grouped.</p>
  
  <p>I could free the allocated strings that were converted by CVT_INT, but freeing the strings used by CVT_STR would result in the struct's strings being freed. I could think of one workaround:
  1. Allocate new space
  2. Copy in the old string
  3. Free the old string.</p>
  
  <pre><code>CVT_STR strcpy((char*)malloc(sizeof(char)*(1+strlen(str))), str)
  </code></pre>
  
  <p>However, on implementing the above, it leads to a crash whenever it is called, and I don't understand why. Could anyone offer me an explanation and a way to solve it/a different route that does the same job? I'm aware it's not very efficient, so suggestions on improving that aspect are also welcome.</p>
  
  <p>Another possibility, I could free only <code>int</code>. However, I couldn't work out how to do this in the macro, as it has to return an int.</p>
  
  <p>Below is an example of me calling the cycle-through-struct macro, containing the conversion macro.</p>
  
  <pre><code>#define STRUCT(type, name, converter) \
          obj-&gt;struct.name = converter(csv[row][col++]);
  STRUCT_FIELDS
  #undef PLAYER
  </code></pre>
  
  <p>Thanks for any help</p>
  
  <p>UPDATE:</p>
  
  <p>Replacing</p>
  
  <pre><code>CVT_STR strcpy((char*)malloc(sizeof(char)*(1+strlen(str))), str)
  </code></pre>
  
  <p>with</p>
  
  <pre><code>CVT_STR strdup(str)
  </code></pre>
  
  <p>worked, but I don't understand why. Perhaps someone could enlighten me?</p>