Set the array pointer within a function

Asked

Viewed 148 times

3

I am trying to write a function that assigns an integer or a list of integers to a pointer, depending on a parameter. But the assignment doesn’t work within it, just outside:

void retorna_algo(int size, int* destino){
  if (size == 1){
    *destino = 1;
  } else if (size == 3) {
    destino = (int[]){1, 2, 3};
  }
}

int main(void) {
  int *ponteiro;

  ponteiro = malloc(sizeof(int));
  retorna_algo(1, ponteiro);
  printf("%d\n", *ponteiro); // Escreve "1" - como esperado

  ponteiro = realloc(ponteiro, sizeof(int)*3);
  retorna_algo(3, ponteiro);

  printf("%d | %d | %d\n", ponteiro[0], ponteiro[1], ponteiro[2]);
  // Escreve "1 | 0 | 0", basicamente mantendo o valor zerado do malloc e realloc

  return 0;
}

Use destino = (int[]){1, 2, 3}; outside the function actually assigns the array to the pointer, but inside it nothing... As if the scope was affecting the assignment. I think it makes some sense, since it is an assignment of the array pointer to the address of the stated literal. And the literal address is discarded when the function is finished.

Leads me to believe that the problem lies in the way the assignment is done (with cast to (int[])), but I couldn’t find any other cast that worked.

  • 1

    The problem is what @Bacco already said. The array created within the function is created in stack that is discarded as soon as the function ends, so any access to it later is invalid and represents Undefined behavior

  • 1

    @Isac thought of for a second example switching pointer with a Static with {1,2,3} off, but then I think it would depend a lot on how it will be used. The side effects would give you a headache if, for example, you tried to change some value. We lacked a little context to know what can or cannot there :) Depending on the scenario makes up for a for making ponteiro[0]=1; ponteiro[1]=2; ponteiro[2]=3 simply, or leave the 3 lines even :)

  • 1

    @Bacco Even I do not know what the purpose of this. I just woke up with a headache with memory management :D

  • @Bacco I find your solution particularly elegant given the context we have. This is because reallocate a new array with malloc not only seems strange, but it would create a memory leak if it didn’t have a free of the array that had already been created in the main.

  • I do not promise, but if you beat some "inspiration" qq time of these elaborate better the answer with some considerations about other parts of the code, and who knows some alternatives. (but there’s a good chance I’ll forget to do it :P )

1 answer

5


The problem is that when making new assignment within the function, you are not taking advantage of the original pointer, but creating a new one (which is discarded in the return).

In these cases, I believe that making a copy is a reasonable solution:

void retorna_algo(int size, int* destino){
  if (size == 1){
    *destino = 1;
  } else if (size == 3) {
    memcpy(destino, (int[]){1, 2, 3}, 3*sizeof(int));
  }
}

See working on IDEONE.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.