简体   繁体   中英

Pointer not returning after function in C

I have to finish a game as University class. This is the checker game.

All works as instructions of my teacher was described except one thing. I need to save history in dynamic memory (each move have 5 characters in char array, so I used malloc to start "historial" and then I used calloc with a size of 5 + 1. There is also "nuevohistorial" to temporary save one move only and then add it to "historial", reusing "nuevohistorial" for the next moves.

I have a char *historial and then I call the GuardarHistorial function.

GuardarHistorial(numjugadas, historial, nuevohistorial);

(numerojugadas is the total number of moves done)

I tried with calloc or realloc.

My code for increase using calloc:

void GuardarHistorial (int *numjugadas, char *historial, char *nuevohistorial) {

int i, j;
char *temp;   

temp = (char *) calloc ((HIST*(*numjugadas) + 1), sizeof(char));

if (temp == NULL) {
    printf("No se ha podido reservar memoria.");
    exit(1);
}    

for (i=0; i<HIST*(*numjugadas-1); i++) {
    temp[i] = historial[i];

}

for (j=0; i < (*numjugadas) * HIST; i++, j++) {
    temp[i] = nuevohistorial[j];
}

historial = temp;    
 }

The firs time I call to function, it save to historial, but "historial" not back to the function where it was declarated, why? It is a pointer...

The code if I use realloc is:

void GuardarHistorial (int *numjugadas, char *historial, char *nuevohistorial) { 

temp = (char *) realloc (historial, (HIST*(*numjugadas) + 1) * sizeof(char));

if (temp == NULL) {
    printf("No se ha podido reservar memoria");
    free(historial);
    exit(1);
}

historial = temp;

i=(*numjugadas-1) * HIST;

for (j=0; i < (*numjugadas) * HIST; i++, j++) {
    historial[i] = nuevohistorial[j];
}  
 }

In this second example it seems to work, and if I open it with Terminal or Netbeans does not show any error and. But testing it with Valgrind, at the second move, it finishes the program with lot of errors in different memory addresses.

How can I solve?

Thanks!

As stated in the answer @Ian Abbott historial needs to be of type char **, not char *, which means that you need to pass in a pointer to a pointer. See for example this post or this post to better understand how it works.

Another possibility is to change

void GuardarHistorial(int *numjugadas, char *historial, char *nuevohistorial)

to

char *GuardarHistorial(int *numjugadas, char *historial, char *nuevohistorial) {
  ....
  return temp;
}

and call it

historial = GuardarHistorial(numjugadas, historial, nuevohistorial);

Also, there is no need to pass numjugadas as a pointer, as you do not modify it in your function.

If you want to pass a pointer back to the caller via the historial parameter, it needs to be of type char ** , not char * .

void GuardarHistorial (int *numjugadas, char **historial, char *nuevohistorial) {

    temp = (char *) realloc (*historial, (HIST*(*numjugadas) + 1) * sizeof(char));

    if (temp == NULL) {
        printf("No se ha podido reservar memoria");
        free(*historial);
        exit(1);
    }

    *historial = temp;

    i=(*numjugadas-1) * HIST;

    for (j=0; i < (*numjugadas) * HIST; i++, j++) {
        temp[i] = nuevohistorial[j];
    }  
}

The function call needs changing to pass a pointer to the pointer:

GuardarHistorial(numjugadas, &historial, nuevohistorial);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM