Change pointer address in a function

0

I'm having trouble changing the address of a pointer inside a function. I declare the pointer inside the function, then step it by parameter to another function. This other function should cause the pointer to point to another address. The problem is that once this function finishes and returns to the one that called it, the pointer does not change.

//imports
#include <stdio.h>
#include<stdlib.h>

#define tam_max_bucket 2

int dir_prof=0;

typedef struct Buck{
 int profundidade;
 int contador;
 int chaves[tam_max_bucket];
}bucket;

typedef struct dir{
 struct Buck *bucket_ref;
}dir_cell;

dir_cell *diretorio;

int make_address(int key, int profundidade){
 int retVal, mask, hashVal, lowBit;
 retVal = 0;
 mask = 1;
 hashVal = key;
 int j;
 for(j=0; j<profundidade; j++){
    retVal = retVal << 1;
    lowBit = hashVal & mask;
    retVal = retVal | lowBit;
    hashVal = hashVal >> 1;
 }
return retVal;
}

int op_find(int key, bucket *found_bucket){
  int address = make_address(key, dir_prof);
  found_bucket = diretorio[address].bucket_ref;
  printf("\n%d\n", found_bucket->profundidade);
  printf("\n%d\n", diretorio[address].bucket_ref->contador);
  printf("\n%d\n", found_bucket->contador);
  int i;
  for(i=0; i<found_bucket->contador; i++){
      if(key == found_bucket->chaves[i])
        return 1;
  }
  return -1;
}

int op_add(int key){
  bucket *found_bucket = (bucket *) malloc(sizeof(bucket));
  printf("\nCont - %d\n", found_bucket->contador); //Imprime o valor do contador assim que found_bucket é alocada
  if(op_find(key, found_bucket) == 1){
    return -1;
  }
  printf("\nNovo valor%d\n", found_bucket->contador); //Imprime o valor de contador de found_bucket após a chamada da função. O valor não se altera, continua o mesmo
  return 1;
  }

void main(){
  diretorio =(dir_cell *) malloc(1*sizeof(dir_cell));
  diretorio[0].bucket_ref =(bucket *) malloc(sizeof(bucket));
  diretorio[0].bucket_ref->profundidade = 0;
  diretorio[0].bucket_ref->contador = 0;
  FILE *chaves;
  chaves = fopen("chaves.txt", "r+");
  if(chaves!=NULL){
      int chave;
      while((fscanf(chaves, "%d\n", &chave))!=EOF){
           printf("%d", chave);
           op_add(chave);
      }
   }
}
    
asked by anonymous 17.07.2017 / 00:42

1 answer

1
  

The problem is that once this function finishes and returns to the   called, the pointer does not undergo any changes

It is true because the pointer value has been copied to another function, the function op_add %% calling op_find :

int op_add(int key){
  bucket *found_bucket = (bucket *) malloc(sizeof(bucket));
  ...
  if(op_find(key, found_bucket) == 1){

Expecting the op_find function to change its value:

int op_find(int key, bucket *found_bucket){
  ...
  found_bucket = diretorio[address].bucket_ref;

But it received a copy of the pointer, so it does not change the original.

The solution to this problem is to pass the pointer address, ie a pointer to a pointer, like this:

int op_find(int key, bucket **found_bucket){ //alterada
  int address = make_address(key, dir_prof);
  *found_bucket = diretorio[address].bucket_ref; //atribuição com base no ponteiro para ponteiro
  printf("\n%d\n", (*found_bucket)->profundidade); //alterada
  printf("\n%d\n", diretorio[address].bucket_ref->contador);
  printf("\n%d\n", (*found_bucket)->contador); //alterada
  int i;
  for(i=0; i<(*found_bucket)->contador; i++){ //alterada
      if(key == (*found_bucket)->chaves[i]) //alterada
        return 1;
  }
  return -1;
}

In addition, always within this last function op_add we change the pointer, with:

*found_bucket = diretorio[address].bucket_ref; //modifica o ponteiro

Here is a memory leak because a bucket was allocated in the previous function, in:

bucket *found_bucket = (bucket *) malloc(sizeof(bucket));

That was not released, and thus need to free % the previous pointer before changing or creating so the pointer without allocating memory.

Finally we can not forget that C does not initialize the memory, just access to a structure that was allocated without assigning initial values will give random values, as can be seen here:

bucket *found_bucket = (bucket *) malloc(sizeof(bucket));
printf("\nCont - %d\n", found_bucket->contador); //não é possível garantir o valor aqui, pois não foi inicializado

If the reason for changing pointers is unclear:

further reading about why it is pointer to pointer instead of normal pointer

    
17.07.2017 / 02:42