c++ – Why am I getting the segfault error?

Question:

My question is that I'm looking on the internet and I've tried things and I don't know how to create a dynamic object and within the dynamic object initialize dynamic arrays and various attributes. I have tried several ways and I get errors, right now it gives me that I have a violation of the segment.

The value of nGarments is a global value, there should be no problem with it. Surely the error is that I have not understood some concept, but I do not know how to move forward, thanks.

The main function is backtracking which is called by main.

struct Solucion{
    int *sActual;
    int *sMejor;
    int dActual;
    int dMejor;
};
void iniciar(Solucion* S){
    S->sActual = new int[nPrendas];
    memset(S->sActual,-1,sizeof(int)*nPrendas);
    S->sMejor = new int[nPrendas];
    memset(S->sMejor,-1,sizeof(int)*nPrendas);
    S->dActual = 0;
    S->dMejor = 0;

}
void borrar(Solucion* S){
    delete[] S->sActual;
    delete[] S->sMejor;
}
void backtracking()
{   
    Solucion *S;
    iniciar(S);
    borrar(S);
    delete S;

}

Answer:

The whole problem lies in this block of code:

void backtracking()
{   
    Solucion *S; //<-- aquí
    iniciar(S);
    borrar(S);
    delete S;

}

If you realize, the pointer S at no time is assigned a base address of an object, it remains with garbage content and this is the reason why it gives a segmentation fault (accessing memory that does not belong to the program).

Solution: You must allocate memory with new .

void backtracking()
{   
    Solucion *S = new Solucion; 
    iniciar(S);
    borrar(S);
    delete S;
}

In this way, the pointer S will point to an object that does belong to the program.

Although this should solve everything, there is another problem and that is that you did not assign any address to the sMejor member either and this causes a segmentation fault to occur.

This is how it should look:

void iniciar(Solucion* S){
    S->sActual = new int[nPrendas];
    memset(S->sActual,-1,sizeof(int)*nPrendas);
    cout<<"ERROR INICIAR1"<<endl;
    //Se reserva un array de X elementos y se asigna la dirección base del array a sMejor.
    S->sMejor = new int[nPrendas];
    memset(S->sMejor,-1,sizeof(int)*nPrendas);
    S->dActual = 0;
    S->dMejor = 0;
}

Upgrade:

If you change the iniciar function parameter to Solucion& , then S will be a reference to Solucion , so you can only pass an argument of type Solucion and not of type Solucion* .

Error example:

void iniciar(Solucion& S)
{
   //code
}

void backtracking()
{   
    Solucion* S = new Solucion; 
    iniciar(S); //error de compilación.
}

One possible solution is to declare the S parameter as a reference to a pointer to Solucion , so you can modify the content of the pointer and the object it points to.

Example:

void iniciar(Solucion*& S)
{
    S->sActual = new int[nPrendas];
    memset(S->sActual,-1,sizeof(int)*nPrendas);
    cout<<"ERROR INICIAR1"<<endl;
    S->sMejor = new int[nPrendas];
    memset(S->sMejor,-1,sizeof(int)*nPrendas);
    S->dActual = 0;
    S->dMejor = 0;
}

A second solution would be to use automatic storage (i.e. the object is created when the function starts and destroyed when the routine finishes its execution):

void iniciar(Solucion& S)
{
   //code
}

void backtracking()
{   
    //El objeto tiene un almacenamiento automático.
    Solucion S; 
    iniciar(S); 
}

And in this way, you avoid reserving memory and freeing it. Don't forget that in the iniciar function you must use the operator . in order to access the members of the structure.

Full code ( solution 2 ):

void borrar(Solucion& S){
    delete[] S.sActual;
    delete[] S.sMejor;
}

void iniciar(Solucion& S)
{
    S.sActual = new int[nPrendas];
    memset(S.sActual,-1,sizeof(int)*nPrendas);
    cout<<"ERROR INICIAR1"<<endl;
    S.sMejor = new int[nPrendas];
    memset(S.sMejor,-1,sizeof(int)*nPrendas);
    S.dActual = 0;
    S.dMejor = 0;
}

void backtracking()
{   
    Solucion S;
    iniciar(S);
    borrar(S);
}

And voila, solution two is simpler than the first.

Scroll to Top