446,194 Members | 817 Online Need help? Post your question and get tips & solutions from a community of 446,194 IT Pros & Developers. It's quick & easy.

# allocate and delete space question

 P: n/a hi all I use matrix & vector function to allocate the space myself in c, typedef struct matrix_array newdata; struct matrix_array{ float **sy,*sxx; }; newdata ndata;//new data struct ndata.sy=matrix(1,nvar,1,nstep); ndata.sxx=vector(1,nstep); the question lies there,if I free the space there,it will be ok,but if I do like this way, rkdumb(vstart,nvar,x1,x2,nstep,(void *)&ndata,derivefunc); use void* to deference the data point, and free it after the function,it will tell me "Segmentation fault",who can tell me what is the reason? thanks a lot float **matrix(long nrl, long nrh, long ncl, long nch) /* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */ { long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; float **m; /* allocate pointers to rows */ m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); if (!m) nrerror("allocation failure 1 in matrix()"); m += NR_END; m -= nrl; /* allocate rows and set pointers to them */ m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float))) ; if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); m[nrl] += NR_END; m[nrl] -= ncl; for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; /* return pointer to array of pointers to rows */ return m; } float *vector(long nl, long nh) /* allocate a float vector with subscript range v[nl..nh] */ { float *v; v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float))); if (!v) nrerror("allocation failure in vector()"); return v-nl+NR_END; } ndata.sy=matrix(1,nvar,1,nstep); Jul 23 '05 #1
5 Replies

 P: n/a On 10 Apr 2005 17:42:34 -0700, "lixiaoyao" wrote: hi all I use matrix & vector function to allocate the space myself in c, Below you'll find my guess as to what is going wrong, but you need to take this question to comp.lang.c. One reason is the C++ approach is quite different than the C implementation you give, and this newsgroup is better suited for a C++ solution to the problem you are working on. [...] rkdumb(vstart,nvar,x1,x2,nstep,(void *)&ndata,derivefunc);use void* to deference the data point, and free it after thefunction,it will tell me"Segmentation fault",who can tell me what is the reason?thanks a lot What does rkdumb free? "free(&ndata)"? "free(ndata.sy)"? Something else? free()-ing a pointer to ndata will fail because ndata isn't dynamically allocated. free()-ing ndata.sxx or ndata.sy will fail because they point not to dynamically allocated memory but to some point before the memory block (keep reading for details). float **matrix(long nrl, long nrh, long ncl, long nch)/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch]*/{ long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; float **m; /* allocate pointers to rows */ m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); if (!m) nrerror("allocation failure 1 in matrix()"); m += NR_END; m -= nrl; Altering m (and m[nrl]) means free(m) (and free(m[nrl])) will fail. free(m+nrl-NR_END) (and free(m[nrl]+ncl-NR_END)) should work. If you must use non-0 based indexing, I recommend using functions to perform the indexing rather than altering m, as it's too easy to corrupt the allocation information for the allocated memory block. For instance, if the size of an allocated block is stored at *(malloc(size)-1), then m[nrl-NR_END-1][ncl-NR_END-1]=0 would make it impossible to free the block of memory. Example indexing functions: typedef struct matrix { long nrl, ncl, nrow, ncol; float **data; } matrix_t; //access functions float* matrix_row(matrix_t matr, long row_idx) { row_idx-=nrl; if (row_idx < matr.nrow) { return matr.data[row_idx]; } return NULL; } float matrix_element(matrix_t matr, long row_idx, long col_idx) { float* row= matrix_row(matr, row_idx); if (row) { col_idx -= matr.ncl; if (col_idx < matr.ncol) { return row[col_idx]; } } return FLT_NAN; } //assignment functions float* set_matrix_row(matrix_t matr, long row_idx, float* row) { row_idx-=nrl; if (row_idx < matr.nrow) { memcpy(matr.data[row_idx], row, matr.ncol); return matr.data[row_idx]; } else return NULL; } float set_matrix_element(matrix_t matr, long row_idx, long col_idx, float val) { float* row= matrix_row(matr, rowIdx); if (row) { col_idx -= matr.ncl; if (col_idx < matr.ncol) { row[col_idx]=val; return val; } } return FLT_NAN; } -- Kanenas Jul 23 '05 #2

 P: n/a hi kanenas I am still wondering. your solutions is suggestive ,Is there someway that I do not need to rewrite the code? rkdumb(vstart,nvar,x1,x2,nstep,(void *)&ndata,derivefunc);use void* to deference the data point, and free it after thefunction,it will tell me"Segmentation fault",who can tell me what is the reason?thanks a lot What does rkdumb free? "free(&ndata)"? "free(ndata.sy)"? Something else? In there,It should free(&ndata),but I do not think it will change ndata. free()-ing a pointer to ndata will fail because ndata isn't dynamically allocated. free()-ing ndata.sxx or ndata.sy will fail because they point not to dynamically allocated memory but to some point before the memory block (keep reading for details). what does this mean?float **matrix(long nrl, long nrh, long ncl, long nch)/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch]*/{ long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; float **m; /* allocate pointers to rows */ m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); if (!m) nrerror("allocation failure 1 in matrix()"); m += NR_END; m -= nrl; Altering m (and m[nrl]) means free(m) (and free(m[nrl])) will fail. free(m+nrl-NR_END) (and free(m[nrl]+ncl-NR_END)) should work. If you must use non-0 based indexing, I recommend using functions to perform the indexing rather than altering m, as it's too easy to corrupt the allocation information for the allocated memory block. For instance, if the size of an allocated block is stored at *(malloc(size)-1), then m[nrl-NR_END-1][ncl-NR_END-1]=0 would make it impossible to free the block of memory. Example indexing functions: typedef struct matrix { long nrl, ncl, nrow, ncol; float **data; } matrix_t; //access functions float* matrix_row(matrix_t matr, long row_idx) { row_idx-=nrl; if (row_idx < matr.nrow) { return matr.data[row_idx]; } return NULL; } float matrix_element(matrix_t matr, long row_idx, long col_idx) { float* row= matrix_row(matr, row_idx); if (row) { col_idx -= matr.ncl; if (col_idx < matr.ncol) { return row[col_idx]; } } return FLT_NAN; } //assignment functions float* set_matrix_row(matrix_t matr, long row_idx, float* row) { row_idx-=nrl; if (row_idx < matr.nrow) { memcpy(matr.data[row_idx], row, matr.ncol); return matr.data[row_idx]; } else return NULL; } float set_matrix_element(matrix_t matr, long row_idx, long col_idx, float val) { float* row= matrix_row(matr, rowIdx); if (row) { col_idx -= matr.ncl; if (col_idx < matr.ncol) { row[col_idx]=val; return val; } } return FLT_NAN; } -- Kanenas Jul 23 '05 #3

 P: n/a float **matrix(long nrl, long nrh, long ncl, long nch)/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch]*/{ long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; float **m; /* allocate pointers to rows */ m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); if (!m) nrerror("allocation failure 1 in matrix()"); m += NR_END; m -= nrl; Altering m (and m[nrl]) means free(m) (and free(m[nrl])) will fail. free(m+nrl-NR_END) (and free(m[nrl]+ncl-NR_END)) should work. If you must use non-0 based indexing, I recommend using functions to perform the indexing rather than altering m, as it's too easy to corrupt the allocation information for the allocated memory block. For instance, if the size of an allocated block is stored at *(malloc(size)-1), then m[nrl-NR_END-1][ncl-NR_END-1]=0 would make it impossible to free the block of memory. also,how does this expalin why it can be free before run the rkdumb(vstart,nvar,x1,x2,nstep,(void *)&ndata,derivefunc); thank you very much BO Jul 23 '05 #4

 P: n/a float **matrix(long nrl, long nrh, long ncl, long nch)/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch]*/{ long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; float **m; /* allocate pointers to rows */ m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); if (!m) nrerror("allocation failure 1 in matrix()"); m += NR_END; m -= nrl; Altering m (and m[nrl]) means free(m) (and free(m[nrl])) will fail. free(m+nrl-NR_END) (and free(m[nrl]+ncl-NR_END)) should work. If you must use non-0 based indexing, I recommend using functions to perform the indexing rather than altering m, as it's too easy to corrupt the allocation information for the allocated memory block. For instance, if the size of an allocated block is stored at *(malloc(size)-1), then m[nrl-NR_END-1][ncl-NR_END-1]=0 would make it impossible to free the block of memory. also.I do not know why "if an allocated block is stored at *(malloc(size)-1), then m[nrl-NR_END-1][ncl-NR_END-1]=0 would make it impossible to free the block of memory." Thanks a lot Jul 23 '05 #5 