Memory allocation issue with multidimensional array - c

#define MAXROWS 88
#define MAXSTATES 10
#define MAXPROBS 6
int obs[MAXROWS]= {0,5,2,3,0,5,2,3,2,4,0,3,5,1,4,3,1,5,2,0,4,4,1,5,3,3,1,4,0,5,1,2,3,0,2,0,5,2,0, 4,4,5,3,0,5,2,5,1,5,4,0,3,1,4,5,2,3,5,1,5,2,4,5,1,5,4,2,5,0,3,4,1,5,2,4,1,5,0,4,2,3,0,5,1,5,2,4,1};//{2,1,0} ;
int q[MAXROWS]= {1};
int s=MAXROWS, i=1,j=0;
double **A;
double **B;
double AD[MAXSTATES][MAXSTATES]={{0,1,0,0,0,0,0,0,0,0},{0,0,1,0,0,0,0,0,0,0},{0,0,0,1,0,0,0,0,0,0},{0,0,0,0,1,0,0,0,0,0},{0.8,0,0,0,0,0.2,0,0,0,0},{0,0,0,0,0,0,1,0,0,0},{0,0,0,0,0,0,0,1,0,0},{0,0,0,0,0,0,0,0,1,0},{0.2,0,0,0,0,0.8,0,0,0,0}};//{{.6,.4},{.3,.7}};//{ { .500, .375, .125 }, { .250,.125, .625 }, { .250,.375,.375 } };
double BD[MAXSTATES][MAXPROBS]={{.167,.167,.167,.167,.167,.167},{.167,.167,.167,.167,.167,.167},{.167,.167,.167,.167,.167,.167},{.167,.167,.167,.167,.167,.167},{.167,.167,.167,.167,.167,.167},{.4,.1125,.1125,.1125,.1125,.15},{.4,.1125,.1125,.1125,.1125,.15},{.4,.1125,.1125,.1125,.1125,.15},{.4,.1125,.1125,.1125,.1125,.15},{.4,.1125,.1125,.1125,.1125,.15}};//{{.1,.3,.6},{.5,.4,.1}};//{ { .60, .20 ,.15, .05}, { .25, .25, .25, .25 }, { .05,.10,.35,.50 } };
double *pi;
double pi2[MAXSTATES] = {1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};//{.4,.6};
double *poolA;
double *curPtrA;
double *poolB;
double *curPtrB;
double pproba=0;
double **delta;
double *pool;
double *curPtr;
int **psi;
int *poolpsi;
int *curPtrpsi;
HMM model;
A = (double** )calloc(MAXSTATES, sizeof(double* ));
poolA = (double *)calloc( MAXSTATES * MAXSTATES, sizeof(double));
curPtrA = poolA;
for( i = 0; i < MAXSTATES; i++)
{
*(A + i) = curPtrA;
curPtrA += MAXSTATES;
}
B = (double** )calloc(MAXSTATES, sizeof(double* ));
poolB = (double *)calloc( MAXSTATES * MAXPROBS, sizeof(double));
curPtrB = poolB;
for( i = 0; i < MAXSTATES; i++)
{
*(B + i) = curPtrB;
curPtrB += MAXPROBS;
}
for(i = 0; i <MAXSTATES; i++)
for(j=0; j< MAXPROBS; j++)
B[i][j] = BD[i][j];
for(i = 0; i < MAXSTATES; i++)
for(j=0; j< MAXSTATES; j++)
A[i][j] = AD[i][j];
pi = (double* )calloc(MAXSTATES, sizeof(double* ));
for(i = 0; i <MAXSTATES; i++)
pi[i] = pi2[i];
model.M=MAXPROBS;
model.N=MAXSTATES;
model.A= A;
model.B = B;
model.pi = pi;
//double delta[6][4];
psi = (int** )calloc(MAXROWS, sizeof(int* ));
poolpsi = (int *)calloc( MAXROWS*MAXSTATES, sizeof(int));
curPtrpsi = poolpsi;
for( i = 0; i < MAXROWS; i++)
{
*(psi + i) = curPtrpsi;
curPtrpsi += MAXSTATES;
}
I start getting error on psi = (int **) ... line about heaps which is like this:
"Windows has triggered a breakpoint in TestProj.exe.
This may be due to a corruption of the heap, which indicates a bug in TestProj.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while TestProj.exe has focus.
The output window may have more diagnostic information."

pi = (double* )calloc(MAXSTATES, sizeof(double* ));
i think you should have sizeof(double) not pointer since its an array of double values.

Allocating memory as follows avoids the need to repeat the name of the type all over the place, and thus you won't mismatch it.
double* pi = calloc(MAXSTATES, sizeof(*pi));

int **psi , i;
psi = malloc( MAXROWS * sizeof(int*));
for( i = 0 ; i < MAXROWS ; i++ )
{
psi[i] = calloc (MAXSTATES, sizeof(int));
}
Try to do that and a little check if psi is not null could be great ^^.

Related

Can't allocate memory for triple pointer

I'm doing a project for school and I have a problem and I can't figure out how to solve it. I'm trying to allocate memory for a triple pointer in a function that I will be able to use it as a 2D array, save data and then use it in a different function. But for some reason I can't use the data once I'm out of the function.
BTW I have to use the variables that is writing in the function (float m1[ROWS][COLS], float m2[ROWS][COLS], float ***C).
int mat_mul(float m1[ROWS][COLS], float m2[ROWS][COLS], float ***C)
{
int i, j, k;
C = (float ***)malloc(sizeof(float*) * 3);
for (i = 0; i < 3; i++) {
C[i] = (float **)malloc(sizeof(float*) * 3);
for (j = 0; j < 3; j++) {
C[i][j] = (float *)malloc(sizeof(float) *3);
}
}
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
(*C)[i][j] = 0;
for (k = 0; k < ROWS; k++) {
(*C)[i][j] += m1[i][k] * m2[k][j];
}
}
}
printf_s("%.1f\n", (*C)[0][0]);
}
int i,j;
float Results[ROWS][COLS];
float Angle1[6], Angle2[6];
Angle_Reader("data_q.csv", &Angle1, &Angle2);
Angle_Converter(&Angle1, &Angle2);
for (i = 0; i < 1; i++) {
float Matrix1[ROWS][COLS] = { {cos(Angle1[i]),-sin(Angle1[i]),L1*cos(Angle1[i])},{sin(Angle1[i]),cos(Angle1[i]),L1*sin(Angle1[i])},{0,0,1} };
float Matrix2[ROWS][COLS] = { {cos(Angle2[i]),-sin(Angle2[i]),L2*cos(Angle2[i])},{sin(Angle2[i]),cos(Angle2[i]),L2*sin(Angle2[i])},{0,0,1} };
mat_mul(&Matrix1, &Matrix2, &Results);
}
printf_s("\n");
printf_s("%.1f\n", Results[0][0]);
This:
for (i = 0; i < 1; i++) {
float Matrix1[ROWS][COLS] = { {cos(Angle1[i]),-sin(Angle1[i]),L1*cos(Angle1[i])},{sin(Angle1[i]),cos(Angle1[i]),L1*sin(Angle1[i])},{0,0,1} };
float Matrix2[ROWS][COLS] = { {cos(Angle2[i]),-sin(Angle2[i]),L2*cos(Angle2[i])},{sin(Angle2[i]),cos(Angle2[i]),L2*sin(Angle2[i])},{0,0,1} };
mat_mul(&Matrix1, &Matrix2, &Results);
}
Should not be in a loop as is.
Either move the declaration above the loop, then in the loop, use index values ( i.e. Matrix2[i][j] ) instead of ROWS, COLS,
float Matrix1[ROWS][COLS] = {0};
float Matrix2[ROWS][COLS] = {0};
//Note: these initializers work only for 3x3 array
//Forcing ROWS == 3 and COLS == 3
float data1[ROWS][COLS] = { {cos(Angle1[0]),-sin(Angle1[1]),L1*cos(Angle1[2])},{sin(Angle1[0]),cos(Angle1[1]),L1*sin(Angle1[2])},{0,0,1} };
float data2[ROWS][COLS] = { {cos(Angle2[0]),-sin(Angle2[1]),L2*cos(Angle2[2])},{sin(Angle2[0]),cos(Angle2[1]),L2*sin(Angle2[2])},{0,0,1} };
...
if(Results)
{
for (i = 0; i < 1; i++)
{
Matrix1[i][j] = data1[i][j];
Matrix2[i][j] = data2[i][j];
...
mat_mul(&Matrix1, &Matrix2, &Results);
}
...or remove the for loop altogether and modify the i and j indexes from Angle1[i] to hard-coded values eg: Angle1[0], Angle1[1],... so that the initializers will populate the 2D arrays.
float Matrix1[ROWS][COLS] = { {cos(Angle1[0]),-sin(Angle1[1]),L1*cos(Angle1[2])},{sin(Angle1[0]),cos(Angle1[1]),L1*sin(Angle1[2])},{0,0,1} };
float Matrix2[ROWS][COLS] = { {cos(Angle2[0]),-sin(Angle2[1]),L2*cos(Angle2[2])},{sin(Angle2[0]),cos(Angle2[1]),L2*sin(Angle2[2])},{0,0,1} };
mat_mul(&Matrix1, &Matrix2, &Results);
Regarding creating memory, Nothing in your code indicates the need for a 3D array. As stated in comments, the reason for float ***C in the mat_mul(., ., float ***C) function prototype is to accommodate passing the address of a 2D matrix ( eg. &Results ), when calling function so that it can be modified. Even then, it would be an improvement to move the logic necessary to create the memory for that variable into its own function, and allocate the memory before it is passed as a variable:
float **Results = Create2D(COLS, ROWS);
if(Results)
{
for (i = 0; i < 1; i++)
{
...
...
mat_mul(&Matrix1, &Matrix2, &Results);
}
//When finished using, free Results
free2D(Results, COLS)
The functions Create2D() and its companion could be implemented as:
float ** Create2D(int c, int r)
{
float **arr;
int y;
arr = calloc(c, sizeof(float *));
for(y=0;y<c;y++)
{
arr[y] = calloc(r, sizeof(float));
}
return arr;
}
void free2D(float **arr, int c)
{
int i;
for(i=0;i<c;i++)
{
free(arr[i]);
}
free(arr);
}

Why Segmentation fault is happening in this situation? Openmp problems

After writing a sequential program, I need to parallelize it. Here is a small part, which for some reason does not work. When N > 64 and 4 threads, the program starts to produce a segmentation error. And with 2 threads everything works fine. I tried to set the environment variable KMP_STACK_SIZE = 128m, but this did not help me. What could be the problem?
#include <omp.h>
void setMatrix(double *matrix, int size) {
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++) {
if (i == j) {
matrix[i * size + j] = 2;
} else
matrix[i * size + j] = 1;
}
}
void setVector(double *vector, int size, int value) {
for (int i = 0; i < size; i++) {
vector[i] = value;
}
}
void clearVec(double *vector, int size) {
for (int i = 0; i < size; i++) {
vector[i] = 0;
}
}
void mulMatrAndVec(double *result, const double *matrix, const double *vector, int size) {
clearVec(result, size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
result[i] += matrix[i * size + j] * vector[j];
}
}
}
void subVectors(double *result, const double *vector1, const double *vector2, int size) {
for (int i = 0; i < size; i++) {
result[i] = vector1[i] - vector2[i];
}
}
void mulMatrAndVecMP(double *result, const double *matrix, const double *vector, int place, int blockSize, int size) {
for (int i = place; i < (place + blockSize); i++) {
for (int j = 0; j < size; j++) {
result[i] += matrix[i * size + j] * vector[j];
}
}
}
int main(int argc, char *argv[]) {
int N = 68;
double *A = (double *) malloc(N * N * sizeof(double));
double *x = (double *) malloc(N * sizeof(double));
double *b = (double *) malloc(N * sizeof(double));
double *u = (double *) malloc(N * sizeof(double));
double *r1 = (double *) malloc(N * sizeof(double));
double *r2 = (double *) malloc(N * sizeof(double));
double *z = (double *) malloc(N * sizeof(double));
double *vec1 = (double *) malloc(N*N * sizeof(double));
double *vec2 = (double *) malloc(N * sizeof(double));
double a = 0;
double bt = 0;
int threadNum, threadCount;
setMatrix(A, N);
setVector(x, N, 0);
setVector(b, N, N + 1);
mulMatrAndVec(vec1, A, x, N);
subVectors(r1, b, vec1, N);
clearVec(vec1, N);
memcpy(z, r1, N * sizeof(double));
memcpy(r2, r1, N * sizeof(double));
omp_set_num_threads(4);
threadCount = omp_get_num_threads();
#pragma omp parallel private(threadNum) shared(threadCount, vec1, A, z)
{
threadNum = omp_get_thread_num();
mulMatrAndVecMP(vec1, A, z, (threadNum * N) / threadCount, N / threadCount, N);
}
free(A);
free(x);
free(b);
free(r1);
free(r2);
free(z);
free(vec1);
free(vec2);
free(u);
return 0;
}
The problem is that you call
threadCount = omp_get_num_threads();
outside the parallel block so it's 1 and your loop inside
mulMatrAndVecMP(vec1, A, z, (threadNum * N) / threadCount, N / threadCount, N);
goes out of bounds.
Setting
threadCount = 4
instead should fix your problem.
As you can read here the call returns the number of threads in the current team, and there's no current team.
Edit: be careful in case N is not divisible by the number of threads: your code skips some lines of the multiplication.

Assign value to pointer to pointer 2d array

I believe I have a declaration incorrect. I have an array that is 2D and an array that is 3D. I'm seg faulting because I'm assigning the value 0 -- or NULL to one of the arrays. I know this is trying to assign the address NULL to the pointer which is invalid.
Maybe I need to dereference the array before assigning? If so, how do I do this? If not, how do I need to declare the arrays?
double **WeightIH = calloc(51*20,sizeof(double **));
double ***Input = calloc(51*40, sizeof(double ***));
DeltaWeightIH[i][j] = 0.0 ;
the easiest way is to use for loops. just like the example below
int i, j = 0;
int rows = 5;
int cols = 2;
int rows2 = 3; // for 3d array
double **arr2d = (double **)calloc(rows, sizeof(double));
double ***arr3d = (double ***)calloc(rows, sizeof(double));
for (i = 0; i < rows; j++)
{
arr2d[i] = (double *)calloc(cols, sizeof(double));
}
arr2d[1][2] = 0.0; //Or *(*(arr2d+1)+2) = 0.0;
//the same thing for 3d it just need another for loop.
for (i = 0; i < rows; j++)
{
arr3d[i] = (double **)calloc(cols, sizeof(double));
for (j = 0; i < cols; j++)
{
arr3d[i][j] = (double *)calloc(rows2, sizeof(double));
}
}
arr3d[1][2][1] = 0.0; //Or *(*(*(arr2d+1)+2)+1) = 0.0;
A simple way to define 5x6x7 matrix hope it helps.
float ***array3D;
array3D = malloc(5 * sizeof(float**));
for ( int i = 0; i < 5; ++i) {
array3D[i] = malloc(6 * sizeof(float*));
for ( int j = 0; j < 6; ++j) {
array3D[i][j] = calloc( 7, sizeof(float));
for ( int k = 0; k < 7; ++k )
array3D[i][j][k] = 1.0;
}
}
I wouldn't use calloc when define array of pointers since you filling them immediately in the same loop.
Don't forget to free, it will eat your memory very quick.
It's not clear from your question whether a contiguous array would satisfy your requirements; but if it does then you can write more simply:
double (*a)[20] = malloc( 51 * sizeof *a );
double (*b)[20][30] = malloc( 10 * sizeof *b );
The innermost dimension goes on the right-hand-side, the other dimensions go on the left.
If you really do need a jagged array you need to write separate allocations for each row.

c allocating space for a 2d array of pointers in a loop

I have a rather large program that requires me to use pointers to 2 dimensional arrays. I'm having a difficult time allocating space for the arrays.
I've already tried allocating the space at the time of declaration but I ran into a million road blocks.
I found code here: Create a pointer to two-dimensional array
I have a 2D array of pointers to an array other_arrays
I have this:
static double other_arrays[51][1];
double (*SumH)[51][1] = &other_arrays;
double (*WeightIH)[51][1] = &other_arrays;
double (*Hidden)[51][1] = &other_arrays;
double (*SumO)[51][1] = &other_arrays;
double (*WeightHO)[51][1] = &other_arrays;
double (*Output)[51][1] = &other_arrays;
double (*DeltaWeightIH)[51][1] = &other_arrays;
double (*DeltaWeightHO)[51][1] = &other_arrays;
for (i = 0; i < 2; i++){
for (j = 0; j < 51; j++){
SumH[j][i] = (double *)malloc(sizeof(double));
WeightIH[j][i] = (double *)malloc(sizeof(double));
Hidden[j][i] = (double *)malloc(sizeof(double));
SumO[j][i] = (double *)malloc(sizeof(double));
WeightHO[j][i] = (double *)malloc(sizeof(double));
Output[j][i] = (double *)malloc(sizeof(double));
DeltaWeightIH[j][i] = (double *)malloc(sizeof(double));
DeltaWeightHO[j][i] = (double *)malloc(sizeof(double));
}
}
When I compile I get: error: array type 'double [1]' is not assignable
I've tried some things I've found online such as SumH[j] = (double *)malloc(sizeof(double));
But then I get: error: array type 'double [51][1]' is not assignable
Or something like this yields the same error:
for (j = 0; j < 51; j++){
SumH[j] = (double *)malloc(sizeof(double));
WeightIH[j] = (double *)malloc(sizeof(double));
Hidden[j] = (double *)malloc(sizeof(double));
SumO[j] = (double *)malloc(sizeof(double));
WeightHO[j] = (double *)malloc(sizeof(double));
Output[j] = (double *)malloc(sizeof(double));
DeltaWeightIH[j] = (double *)malloc(sizeof(double));
DeltaWeightHO[j] = (double *)malloc(sizeof(double));
}
SOLUTION
I didn't cast malloc
*SumH[j][i] = *(double *)malloc(sizeof(double));
If you want pointers to arrays and want to initialize them, then you should be doing things much more simply:
double (*SumH)[5][2] = malloc(sizeof(*SumH));
double (*WeightIH)[5][2] = malloc(sizeof(*WeightIH));
Now you can use:
int k = 0;
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 2; j++)
{
(*SumH)[i][j] = k;
(*WeightIH)[i][j] = k++;
}
}
Note that an array dimension of [1] is close to pointless.
FWIW, valgrind gives the following code a clean bill of health:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
double (*SumH)[5][2] = malloc(sizeof(*SumH));
double (*WeightIH)[5][2] = malloc(sizeof(*WeightIH));
int k = 0;
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 2; j++)
{
(*SumH)[i][j] = k;
(*WeightIH)[i][j] = k++;
}
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 2; j++)
printf("[%f, %f]", (*SumH)[i][j], (*WeightIH)[i][j]);
putchar('\n');
}
free(SumH);
free(WeightIH);
return 0;
}
The output is not very exciting:
[0.000000, 0.000000][1.000000, 1.000000]
[2.000000, 2.000000][3.000000, 3.000000]
[4.000000, 4.000000][5.000000, 5.000000]
[6.000000, 6.000000][7.000000, 7.000000]
[8.000000, 8.000000][9.000000, 9.000000]
If you want to allocate 2d arrays:
/* allocate 2d arrays */
double (*SumH)[51][1] = malloc(51*1*sizeof(double));
double (*WeightIH)[51][1] = malloc(51*1*sizeof(double));
double (*Hidden)[51][1] = malloc(51*1*sizeof(double));
double (*SumO)[51][1] = malloc(51*1*sizeof(double));
double (*WeightHO)[51][1] = malloc(51*1*sizeof(double));
double (*Output)[51][1] = malloc(51*1*sizeof(double));
double (*DeltaWeightIH)[51][1] = malloc(51*1*sizeof(double));
double (*DeltaWeightHO)[51][1] = malloc(51*1*sizeof(double));
/* ... */
free(DeltaWeightHO);
free(DeltaWeightIH);
free(Output);
free(WeightHO);
free(SumO);
free(Hidden);
free(WeightIH);
free(SumH);
Usage would be ... (*SumH)[j][i] ...
I doubt this is want you wanted.
To allocate pointers to the first row of 2d arrays:
/* allocate pointers to first row of 2d arrays */
double (*SumH)[1] = malloc(51*1*sizeof(double));
double (*WeightIH)[1] = malloc(51*1*sizeof(double));
double (*Hidden)[1] = malloc(51*1*sizeof(double));
double (*SumO)[1] = malloc(51*1*sizeof(double));
double (*WeightHO)[1] = malloc(51*1*sizeof(double));
double (*Output)[1] = malloc(51*1*sizeof(double));
double (*DeltaWeightIH)[1] = malloc(51*1*sizeof(double));
double (*DeltaWeightHO)[1] = malloc(51*1*sizeof(double));
Usage would be ... SumH[j][i] ...
To allocate array of pointers to rows
/* allocate array of pointers to rows */
double (*SumH[51])[1];
for(i = 0; i < sizeof(SumH)/sizeof(SumH[0]); i++)
SumH[i] = malloc(1*sizeof(double));
Usage would be ... SumH[j][i] ...

C: free() invalid pointer; without changing address

I'm using C (not C++) and getting the following error:
Error in './c_rk4': free(): invalid pointer: 0x0000000000a911c0
I was able to trace the error back to the lines (1) and (2). The error in (1) does not occur, if I comment out the line I marked. All other free() usages do not produce errors and the program runs as wished if I comment out all lines with free().
I checked with lines like printf("%p\n", y_n); that the address of y_n is the same after malloc() and before free() (and exactly the address in the error message).
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
void odesolver_rk4 (void (*)(double, _Complex double *, _Complex double **),
int, double,
int, _Complex double *, _Complex double ***);
void testfunc (double, _Complex double *, _Complex double **);
int main (int argc, char *argv[argc]) {
const int t_num = 300;
const int y_num = 2;
_Complex double **y_res;
y_res = malloc(t_num*sizeof(_Complex double *));
for (int i = 0; i < t_num; i++)
y_res[i] = malloc(y_num*sizeof(_Complex double));
odesolver_rk4(testfunc, t_num, 20.0, y_num, (_Complex double []){1.0, 0.0}, &y_res);
for (int i = 0; i < t_num; i++) {
for (int j = 0; j <= y_num; j++) {
printf("%f %f ", creal(y_res[i][j]), cimag(y_res[i][j]));
}
printf("\n");
}
for (int i = 0; i < t_num; i++)
free(y_res[i]); // error (2)
free(y_res);
return 0;
}
void odesolver_rk4 (void (*func)(double, _Complex double *, _Complex double **),
int t_num, double t_end,
int y_num, _Complex double *y_start, _Complex double ***y_res) {
double t_step = t_end/t_num;
double t_n = 0;
_Complex double *y_n, *y_A, *y_B, *y_C;
_Complex double *dy_n, *dy_A, *dy_B, *dy_C;
y_n = malloc(y_num*sizeof(_Complex double));
y_A = malloc(y_num*sizeof(_Complex double));
y_B = malloc(y_num*sizeof(_Complex double));
y_C = malloc(y_num*sizeof(_Complex double));
dy_n = malloc(y_num*sizeof(_Complex double));
dy_A = malloc(y_num*sizeof(_Complex double));
dy_B = malloc(y_num*sizeof(_Complex double));
dy_C = malloc(y_num*sizeof(_Complex double));
for (int j = 0; j < y_num; j++)
y_n[j] = y_start[j];
(*y_res)[0][0] = t_n;
for (int j = 0; j < y_num; j++)
(*y_res)[0][j + 1] = y_start[j];
for (int i = 1; i < t_num; i++) {
func(t_n, y_n, &dy_n);
for (int j = 0; j < y_num; j++)
y_A[j] = y_n[j] + dy_n[j]*t_step/2;
func(t_n + t_step/2, y_A, &dy_A);
for (int j = 0; j < y_num; j++)
y_B[j] = y_n[j] + dy_A[j]*t_step/2;
func(t_n + t_step/2, y_B, &dy_B);
for (int j = 0; j < y_num; j++)
y_C[j] = y_n[j] + dy_B[j]*t_step;
func(t_n + t_step, y_C, &dy_C);
for (int j = 0; j < y_num; j++) {
y_n[j] += t_step/6*(dy_n[j] + 2*(dy_A[j] + dy_B[j]) + dy_C[j]);
(*y_res)[i][0] = t_n;
(*y_res)[i][j + 1] = y_n[j]; // something goes wrong here for (1)
}
t_n += t_step;
}
free(y_n); // error (1)
free(y_A);
free(y_B);
free(y_C);
free(dy_n);
free(dy_A);
free(dy_B);
free(dy_C);
}
void testfunc (double t, _Complex double *y, _Complex double **dy) {
(*dy)[0] = -y[1];
(*dy)[1] = y[0];
}
The problem is this loop:
for (int j = 0; j < y_num; j++)
and this line of code:
(*y_res)[i][j + 1] = y_n[j]
Either your loop needs to be j < y_num - 1 or your expression should use [j]. Otherwise, you are stepping past the end of the y_res array. When you do that, you are overwriting the malloc header for the y_n allocation which is why free() later complains that it is an invalid pointer.
By the way, valgrind is a really good tool for finding these kinds of problems.
http://valgrind.org
Also recommended from the comments is AddressSanitizer:
http://clang.llvm.org/docs/AddressSanitizer.html

Resources