Hi Andreas,
I was not entirely clear. What I meant to say is you cannot do it with a
single call to malloc and expect the two C bracket operators to behave like
a 2D matrix would if it had been statically allocated (e.g. D[row][col]).
For the bracket operators to work, D would have to be an array of row
pointers each pointing to an int array (or offset in a flat array as you
suggested). The patch in question does not allocate this separate array of
pointers. My patch, and the previous mummer-help patches, works similarly to
your suggestion, but does the indexing with arithmetic rather than pointers
to save space. It allocates a single array D of size nRows*nColumns and then
indexes a cell (r,c) by accessing D[r*nColumns+c].

The latest patch that was forwarded did the following to dynamically
allocate a 2D matrix of dimension MxN:

int * D_buf = (int *) calloc ( M*N, sizeof(int) ) ;
int ** D = &D_buf ;

This allocates an array of M*N ints pointed to by D_buf. Then it gets a
pointer to the D_buf pointer and calls it D. Then to access element (r,c) of
the presumed matrix it would call:

D[r][c]

The pointer arithmetic would work out to:

*(*(D+r)+c)

If D were allocated as a separate array of int (row) pointers and
initialized as you suggest, this would work. But D is not an array here, it
is a pointer to the int pointer D_buf. So D+r will be an uninitialized
location. This is what lead to the memory errors.

Best,
-Adam


On Tue, Sep 15, 2009 at 4:28 PM, Andreas Tille <[email protected]> wrote:

> On Tue, Sep 15, 2009 at 10:26:35AM -0400, Adam Phillippy wrote:
> > Hi Charles,
> > I tested the patch you forwarded and it was nonfunctional. It attempted
> to
> > construct a two-dimensional array "D" of dimensions (M+1 x N+1) like so:
> >
> > *   D_buf  = (int  *) calloc ( (M+1)*(N+1), sizeof(int) ) ;
> > **   D  = &D_buf ;
> > *
> >
> >
> > This compiles, but doesn't work. There is no way to allocate a 2D matrix
> > dynamically by only using malloc.
>
> Well, I do not question whether the patch is right or wrong but this
> statement in itself is definitely wrong.  You can perfectly allocate a
> flat memory area with pointers (to store for instance the data rows of
> your aray).  Moreover you allocate a vector of pointers with the number
> of rows you want to store.  Once you have done this you loop over the
> pointer elements of this vector and let them point into the flat array
> with an offset of (row number)*(number of columns)*(size of array
> element).
>
> The reason why this works is the syntactical equality of
>
>   *(ptr + i)   and   ptr[i]
>
> The advantage of this approach is that you can handle all array elements
> equally in a flat loop if the context needs no array position.  For
> instance I have once written an image processing program which needed to
> process a negativ of the image which is the same process for any pixel
> regardless of the position.  That works quite fast with the method
> described above and is a very common way to store data on C.  At the
> same time you always have to make sure that the array is initialised
> correctly - in C you aways buy performance by giving away the safety
> against memory corruption.
>
> > To do the proper pointer arithmetic the
> > D[row][col] operators used later in this source need to know at least one
> > dimension of the matrix.
>
> As I tried to explain above: The theory says this is not true.
>
> > This is known for static arrays, but not for
> > dynamic arrays. The patch you forwarded always leads to a memory access
> > error.
>
> I can not assure that the patch above might not have some memory access
> problems (and I currently have no time to verify).  But that's an issue
> of the actual implementation - not the general principle.
>
> > I implemented my own patch that handles the 2D pointer arithmetic in a
> small
> > wrapper class. This new version is tested and dynamically allocates the
> > memory, so it should fit your needs. You can find the new version of the
> > "annotate.cc" file here:
> >
> >
> http://mummer.cvs.sourceforge.net/viewvc/mummer/MUMmer/src/tigr/annotate.cc?revision=1.3&view=markup
> >
> > This is included in a new MUMmer release (v3.22) I cut last week.
>
> It is fine for me if it works - so there is no need for sticking to the
> solution I suggested above.  I just wanted to correct general statements
> about C here on a public list.  Thanks for working on MUMmer and I
> think it is fine to fetch the new release once it is released instead of
> fiddling around with patches of the old version.
>
> Kind regards
>
>      Andreas.
>
> --
> http://fam-tille.de
> Klarmachen zum Ändern!
>

Reply via email to