title: C free malloc'd structure members and struct
body: <p>I have a problem when I run try to free anything within this struct.  First the struct definition in the header:</p>
  
  <pre><code>    typedef struct{
  int* rType;
  unsigned long int numCols;
  char* rString;  //The literal string, NULL delimited
  int rsSize;     //The size of the string, since NULLS can't be used to find the string end
  int* colsIndex; //Where each new column starts in rString
  long* iColVals;   //integer version of the column
  double* dColVals; //double precision value of column
  }  row_t ;
  </code></pre>
  
  <p>Then here is where an instance of the struct can be created:</p>
  
  <pre><code>row_t* delimitLine(char* line, char* delimList, char delimListSize)
  {
  row_t* thisRow;
  .
  .
  .
  //Make a place for this stuff in memory
  thisRow = (row_t*) malloc(sizeof(row_t));
  if(thisRow==NULL) return NULL;
  .
  .
  .
  thisRow-&gt;rString = line;
  
  //Make Row Mem
  
      //colsIndex
      thisRow-&gt;colsIndex = (int*) malloc(numCols*sizeof(int));
      if(thisRow-&gt;colsIndex==NULL) return NULL;   
  
      //rType
      thisRow-&gt;rType = (int*) malloc(numCols*sizeof(int));
      if(thisRow-&gt;rType==NULL) return NULL;   
  
      //iColVals
      thisRow-&gt;iColVals = (long*) malloc(numCols*sizeof(long));
      if(thisRow-&gt;iColVals==NULL) return NULL;    
  
      //dColVals
      thisRow-&gt;dColVals = (double*) malloc(numCols*sizeof(double));   
      if(thisRow-&gt;dColVals==NULL) return NULL;    
  .
  .
  .
  return thisRow;
  </code></pre>
  
  <p>Then here is how "line" is created:</p>
  
  <pre><code>char* RBreadLine(fifo_t* fifo)
  {
  char* outbuf = NULL;
  .
  .
  .
  outbuf = (char*) malloc(sizeof(char)*(cnt+1));
  .
  .
  .
  return outbuf;
  }
  </code></pre>
  
  <p>Finally the calling sequence:</p>
  
  <pre><code>main()
  {
  row_t* row = NULL;
  .
  .
  .
  while(kg&gt;=0)
  {
  //test condition to exit loop not shown
  line = RBreadLine(fifo);
  .
  .
  .
  
   row = delimitLine(line, delimList, delimListSize);
  //some code to manipulate the row data here
   printRow(row);
   rowDestructor(row);
  
  
  
  }
  
  }
  </code></pre>
  
  <p>The program operates as expected when I comment out the call to rowDestructor, but crashes if I try to free anything.  I have tried commenting all lines except for an individual member of struct and still get crashes, so I am doing something wrong here.</p>
  
  <p>The idea is to have a large text file processing program that reads line-by-line and lets me do stuff to manipulate the row data, then printRow() outputs the final result.</p>
  
  <p>The simple test case was to just output the values as they come out of the delimitLine function (which just allocates memory and populates the row struct with data).</p>
  
  <p>When this process has finished, I should want to free the memory and start over.  This program works as expected if I do not make a call to the destructor, but instead simply orphan these pointers each time there is a new call to RBreadLine() and delimitLine().</p>
  
  <p>If I make a call to rowDestructor(), then the program crashes after the first line (on the first call to rowDestructor() ):</p>
  
  <pre><code> Now to start outputting line
      1)  2)  3)  4)  5)  6)  7)  8)  9)  10)  (-10)63.116722551236001948     0       0       0       0       1       1       1       1       1       0    1
  
      Aborted (core dumped)
  </code></pre>
  
  <p>Perhaps there is something I don't understand about malloc() or free(), but it seems if I can access valid data from the struct members without errors and without causing a crash, then free should be able to free the mem that has been malloc'd.  </p>
  
  <p>Perhaps I am just doing something bad by passing these pointers all around (like passing the pointer to "line" to a function which assigns it to a struct member) but in my mind it's all well accounted.  I know every member of the struct gets malloc'd, and so I should be able to just free it all as I work my way up then free the struct.  Then I can dump another pointer onto the row struct and go at it again.</p>
  
  <p>The reason I am doing this is because I want to be able to process extremely large data sets.  This is a structural rewrite of a program that used to load it all into memory with an fread, then process it, but some of my data sets cause the computer to run out of memory...so I will resort to a block processing approach.</p>
  
  <p>Once I can successfully free a row, then I can build on this by making a row_t**, where I can cycle rows onto the row_t** using a FIFO buffer concept, which will then allow me to seek the text files forward and backward by a reasonable amount (say for application of FIR filters) but won't require having the whole file loaded to memory.</p>
  
  <p>For example, a row FIFO would store these new row_t* structs onto a row_t** and I free the old ones after I fill the circular buffer and begin to overwrite the old pointers...this is where I am going with this.</p>
  
  <p>I think having an answer to this question will be a breakthrough in my understanding of malloc() and free(), or maybe clear something up regarding pointers and structs.</p>
  
  <p>Thanks for any input.</p>
  
  <p>EDIT:
  I apologize for overlooking the most important part of my question:</p>
  
  <pre><code>void rowDestructor(row_t* thisRow)
  {
      //rString
      free(thisRow-&gt;rString);
  
      //colsIndex
      free(thisRow-&gt;colsIndex);   
  
      //rType
      free(thisRow-&gt;rType);   
  
      //iColVals
      free(thisRow-&gt;iColVals);    
  
      //dColVals
      free(thisRow-&gt;dColVals);
  
      //finally kill the whole thing
      free(thisRow);
  }
  </code></pre>
  
  <p>And, since others mentioned compiler flags, here is what I am using:</p>
  
  <pre><code>gcc  -Wall laproc.c utils.c csvsurgeon.c -lm -o csv-surgeon
  </code></pre>
  
  <p>(laproc.c is my specific signal processing code needing to be linked with math lib, and in this example I have simplified it to where these functions are not called to rule them out)</p>
  
  <p>I am using this version of gcc:</p>
  
  <pre><code>$ gcc -v
  Using built-in specs.
  COLLECT_GCC=gcc
  COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-cygwin/4.5.3/lto-wrapper.exe
  Target: i686-pc-cygwin
  Configured with: /gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gcc-4.5.3/configure --srcdir=/gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gc
  c-4.5.3 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --datadir=/usr/share --localstatedir=/var --sysco
  nfdir=/etc --datarootdir=/usr/share --docdir=/usr/share/doc/gcc4 -C --datadir=/usr/share --infodir=/usr/share/info --mandir=/usr/share/man -v --with-g
  mp=/usr --with-mpfr=/usr --enable-bootstrap --enable-version-specific-runtime-libs --libexecdir=/usr/lib --enable-static --enable-shared --enable-shar
  ed-libgcc --disable-__cxa_atexit --with-gnu-ld --with-gnu-as --with-dwarf2 --disable-sjlj-exceptions --enable-languages=ada,c,c++,fortran,java,lto,obj
  c,obj-c++ --enable-graphite --enable-lto --enable-java-awt=gtk --disable-symvers --enable-libjava --program-suffix=-4 --enable-libgomp --enable-libssp
   --enable-libada --enable-threads=posix --with-arch=i686 --with-tune=generic --enable-libgcj-sublibs CC=gcc-4 CXX=g++-4 CC_FOR_TARGET=gcc-4 CXX_FOR_TA
  RGET=g++-4 GNATMAKE_FOR_TARGET=gnatmake GNATBIND_FOR_TARGET=gnatbind --with-ecj-jar=/usr/share/java/ecj.jar
  Thread model: posix
  gcc version 4.5.3 (GCC)
  </code></pre>
  
  <p>Perhaps that is my problem...
  I have recompiled with the other following gcc versions:</p>
  
  <pre><code>Using built-in specs.
  COLLECT_GCC=C:\Program Files\CodeBlocks\MinGW-newer\bin\gcc.exe
  COLLECT_LTO_WRAPPER=c:/program files/codeblocks/mingw-newer/bin/../libexec/gcc/mingw32/4.5.2/lto-wrapper.exe
  Target: mingw32
  Configured with: ../../src/gcc-4.5.2/configure --build=mingw32 --enable-languages=c,c++,ada,fortran,objc,obj-c++ --enable-threads=win32 --enable-libgo
  mp --enable-lto --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gnu-ld --disable-nls --disable-wi
  n32-registry --disable-symvers --disable-werror --prefix=/mingw32tdm --with-local-prefix=/mingw32tdm --enable-cxx-flags='-fno-function-sections -fno-d
  ata-sections' --with-pkgversion=tdm-1 --enable-sjlj-exceptions --with-bugurl=http://tdm-gcc.tdragon.net/bugs
  Thread model: win32
  gcc version 4.5.2 (tdm-1)
  </code></pre>
  
  <p>And another version</p>
  
  <pre><code>Using built-in specs.
  Target: mingw32
  Configured with: ../../gcc-4.4.1/configure --prefix=/mingw --build=mingw32 --enable-languages=c,ada,c++,fortran,objc,obj-c++ --disable-nls --disable-w
  in32-registry --enable-libgomp --enable-cxx-flags='-fno-function-sections -fno-data-sections' --disable-werror --enable-threads --disable-symvers --en
  able-version-specific-runtime-libs --enable-fully-dynamic-string --with-pkgversion='TDM-2 mingw32' --enable-sjlj-exceptions --with-bugurl=http://www.t
  dragon.net/recentgcc/bugs.php
  Thread model: win32
  gcc version 4.4.1 (TDM-2 mingw32)
  </code></pre>
  
  <p>With the 4.4.1 version, it will seg fault at different points in the run.  On a couple runs it even made it through once without seg faulting, so perhaps I have a compiler problem.  Because I have cygwin, perhaps the compilers are inter-mixing utilities and linkers (using the wrong directory for "/bin").</p>
  
  <p>I hope I have included enough to make it clear what I am doing with these malloc'd pointers now that I have included the rowDestructor() code.  Thanks for the comments so far.</p>
  
  <p>If there is inherently anything wrong with my C implementation I would like to fix it.  In the meantime I will clean up my dev environment and see if I can get better results by ensuring the correct path to all components.</p>