Program crash when using calloc (works fine when in debug)

728 views Asked by At

My program works fine in debug mode but when I try it in release, it always crash when arriving when I use a calloc. The weird thing is that I use exactly the same way to write my calloc several times in a row and the crash only occurs the third time...

This is a bit of my code for you to get what I mean :

    #include <stdio.h>
#include <math.h>
#include <dir.h>
#include <stdlib.h>

#include "Normes.h"
#define   EPS 1.0e-14


void atimes(int n, float x[], float r[], int itrnsp, int *ija, float *sa);
void dsprsax(float *sa, int *ija, float *x, float *b, int n);
void dsprstx(float* sa, int *ija, float *x, float *b, int n);
float produit_scalaire(float *x, float *y, int n);
void asolve(int n, float b[], float x[], int itrnsp, int *ija, float *sa);




int linbcg(int n, float b[], float x[], int itol, float tol, int itmax, int *iter, float *err, int *ija, float *sa)
{

    *iter = 0;
    int flag;
    float bnrm2;
    float omega;
    float rho;
    float beta;
    float rho_1;
    float alpha;
    float resid;
    int i;

    float *r=NULL;
    float *vecteur_temporaire=NULL;
    float *r_tilde=NULL;
    float *p=NULL;
    float *p_hat=NULL;
    float *v=NULL;
    float *s=NULL;
    float *s_hat=NULL;
    float *t=NULL;



vecteur_temporaire=calloc((n+1), sizeof(float));
        if (vecteur_temporaire==NULL)
        {
            exit(0);
        }

printf("\nok1\n");

r=calloc((n+1), sizeof(float));
        if (r==NULL)
        {
            exit(0);
        }

printf("\nok2\n");

r_tilde=calloc((n+1), sizeof(float));
        if (r_tilde==NULL)
        {
            exit(0);
        }

printf("\nok3\n");

p=calloc((n+1), sizeof(float));
        if (p==NULL)
        {
            exit(0);
        }

p_hat=calloc((n+1), sizeof(float));
        if (p_hat==NULL)
        {
            exit(0);
        }

v=calloc((n+1), sizeof(float));
        if (v==NULL)
        {
            exit(0);
        }

s=calloc((n+1), sizeof(float));
        if (s==NULL)
        {
            exit(0);
        }

s_hat=calloc((n+1), sizeof(float));
        if (s_hat==NULL)
        {
            exit(0);
        }

t=calloc((n+1), sizeof(float));
        if (t==NULL)
        {
            exit(0);
        }

    bnrm2 = norme2(b, n);
    if (bnrm2==0)
    {
        bnrm2=1;
    }


    atimes(n, x, vecteur_temporaire, 0, ija, sa);
    for (i=1; i<=n; i++)
    {
        r[i] = b[i] - vecteur_temporaire[i];
    }

    *err = norme2(r, n)/bnrm2;
    if (*err < tol) return 0;

    omega = 1.0;

    for (i=1; i<=n; i++)
    {
        r_tilde[i] = r[i];
    }


    while (*iter<=itmax)
    {
        (*iter)++;
         rho = produit_scalaire(r, r_tilde, n);

        if (rho==0)
        {
            return 0;
        }

        if (*iter>1)
        {
            beta = (rho/rho_1)*(alpha/omega);


            for (i=1; i<=n; i++)
            {
                p[i] = r[i]+beta*(p[i] - omega*v[i]);
            }
        }
        else
        {
            for (i=1; i<=n; i++)
            {
                p[i] = r[i];
            }
        }
//printf("\nrho=%.2f   iter=%d   p[1]=%.2f", rho, *iter, p[1]);


        asolve(n, p, p_hat, 0, ija, sa);

        atimes(n, p_hat, v, 0, ija, sa);

        alpha = rho/(produit_scalaire(r_tilde, v, n));

        for (i=1; i<=n; i++)
            {
                s[i] = r[i] - alpha*v[i];
            }

        if (norme2(s, n)<tol)
        {
            for (i=1; i<=n; i++)
            {
                x[i] = x[i] + alpha*p_hat[i];
            }
        resid = norme2(s, n)/bnrm2;
        }

        asolve(n, s, s_hat, 0, ija, sa);

        atimes(n, s_hat, t, 0, ija, sa);
//printf("\nnorme(s) = %.2f , norme(s_hat) = %.2f\n\n", norme2(s, n), norme2(s_hat, n));


//printf("\nt = (%.2f,%.2f,%.2f,%.2f)   omega = %.2f", t[1], t[2], t[3], t[4], omega);
        omega = produit_scalaire(t, s, n)/produit_scalaire(t, t, n);
//printf("\t... %.2f", omega);
        for (i=1; i<=n; i++)
            {
                x[i] = x[i] + alpha*p_hat[i]+omega*s_hat[i];
                r[i] = s[i] - omega*t[i];
            }

        *err = norme2(r, n)/bnrm2;
//printf("\niter = %d  ,  err = %.2f , numerr = %.2f , omega = %.2f, t = (%.2f, %.2f, %.2f, %.2f)", *iter, *err, norme2(r, n), omega, t[1], t[2], t[3], t[4]);

        if (*err<=tol)
        {
            return 0;
        }

        if (omega == 0)
        {
            return 0;
        }

        rho_1=rho;
    }


    if (*err<=tol)                  //manque une condition mais on essaie comme ça
    {
        flag =0;
    }
    else if (omega == 0.0)
    {
        flag = -2;
    }
    else if (rho == 0.0)
    {
        flag = -1;
    }
    else
    {
        flag =1;
    }



free(r);
free(r_tilde);
free(p);
free(p_hat);
free(v);
free(s);
free(s_hat);
free(t);
free(vecteur_temporaire);


    return flag;
}
/*flag indique la réussite de l'algorithme :
flag = 0 : solution trouvee au taux d'errer impose
flag = 1 : pas de convergence apres le nombre maximum de convergences autorisees
flag = -1 : breakdown : rho = 0
flag = -2 : breakdown : omega = 0
*/







void atimes(int n, float x[], float r[], int itrnsp, int *ija, float *sa)
{

    void dsprsax(float sa[], int ija[], float x[], float b[], int n);

    void dsprstx(float sa[], int ija[], float x[], float b[], int n);
            //These are float versions of sprsax and sprstx. if (itrnsp) dsprstx(sa,ija,x,r,n);

    if (itrnsp) dsprstx(sa, ija, x, r, n);
    else dsprsax(sa, ija, x, r, n);
}



void dsprsax(float *sa, int *ija, float *x, float *b, int n)
{
    void nrerror();
    int i,k;

    if (ija[1] != n+2) printf("dsprsax: mismatched vector and matrix");
    for (i=1;i<=n;i++) {
        b[i]=sa[i]*x[i];
        for (k=ija[i];k<=ija[i+1]-1;k++) b[i] += sa[k]*x[ija[k]];
    }
}


void dsprstx(float* sa, int *ija, float *x, float *b, int n)
{
    void nrerror();
    int i,j,k;
    if (ija[1] != n+2) printf("mismatched vector and matrix in dsprstx");

    for (i=1;i<=n;i++) b[i]=sa[i]*x[i];

    for (i=1;i<=n;i++) {

        for (k=ija[i];k<=ija[i+1]-1;k++) {
            j=ija[k];
            b[j] += sa[k]*x[i];
            }
    }
}

float produit_scalaire(float *x, float *y, int n)
{
    float ans = 0;
    int i;

    for (i=1; i<=n; i++)
    {
        ans = ans + x[i]*y[i];
    }

return ans;
}


void asolve(int n, float b[], float x[], int itrnsp, int *ija, float *sa)
    {
        int i;

        for(i=1;i<=n;i++) x[i]=b[i];  /*(sa[i]!=0 ? b[i]/sa[i] : b[i]);*/
        //The matrix A is the diagonal part of A, stored in the first n elements of sa. Since the transpose matrix has the same diagonal, the flag itrnsp is not used.
        return;
    }

So here I initialize several pointers then try to allocate them, it works fine for the first two (vecteur_temporaire and r) but fail when trying to allocate the third, r_tilde (ie. on my console, ok1 and ok2 are printed but the program crash before printing ok3).

I don't think I lack memory (here n = 21 so that's not so bad, and I tested printing something if r==NULL but nothing is printed).

Do you know what can be the cause of such a problem? I'm not really surprised it works in debug mode (apparently it's usual), but I can't get why it works twice but not the third time. Thanks for your help !

0

There are 0 answers