Malloc dentro de uma chamada de função parece estar sendo libertado em troca?

StackOverflow https://stackoverflow.com/questions/105477

  •  01-07-2019
  •  | 
  •  

Pergunta

Eu acho que eu tenho-o para o caso mais básico:

int main(int argc, char ** argv) {
  int * arr;

  foo(arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int * arr) {
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
}

A saída é a seguinte:

> ./a.out 
 car[3]=-1869558540
 a.out(4100) malloc: *** error for object 0x8fe01037: Non-aligned pointer
                         being freed
 *** set a breakpoint in malloc_error_break to debug
>

Se alguém pode lançar luz sobre onde o meu entendimento está falhando, isso seria muito apreciado.

Foi útil?

Solução

Você passa o ponteiro por valor, não por referência, então o que você faz com arr foo dentro não vai fazer a diferença fora da função foo. Como m_pGladiator escreveu é uma maneira de declarar uma referência ao ponteiro assim (. Só é possível em C ++ btw C não sabe sobre referências):

int main(int argc, char ** argv) {
  int * arr;

  foo(arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int * &arr ) {
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
}

Outra forma (melhor IMHO) é não passar o ponteiro como um argumento, mas para retornar um ponteiro:

int main(int argc, char ** argv) {
  int * arr;

  arr = foo();
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

int * foo(void ) {
  int * arr;
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
  return arr;
}

E você pode passar um ponteiro para um ponteiro. Essa é a maneira C passar por referência. Complica a sintaxe um pouco, mas bem - que é como C é ...

int main(int argc, char ** argv) {
  int * arr;

  foo(&arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int ** arr ) {
  (*arr) = (int*) malloc( sizeof(int)*25 );
  (*arr)[3] = 69;
}

Outras dicas

Você alocados arr em foo, mas esse valor ponteiros é armazenado na pilha de chamadas. Se você quiser fazer isso, fazê-lo como este:

void foo( int ** arr) {
    *arr = (int *)malloc( sizeof(int) * 25 );
    (*arr)[3] = 69;
}

E no principal, simplesmente passar um ponteiro para foo (como foo (& arr))

foo recebe uma cópia local do ponteiro int, alloactes memória para ele e vazamentos que memória quando ele sai do escopo.

Uma maneira de corrigir isso para obter foo para retornar o ponteiro:

int * foo() {
  return (int*) malloc( sizeof(int)*25 );
}

int main() {
    int* arr = foo();
}

Outra é passar foo um ponteiro para um ponteiro

void foo(int ** arr) {
   *arr = malloc(...);
}

int main() {
    foo(&arr);
}

C ++ que é mais simples de modificar foo para aceitar uma referência a um ponteiro. A única mudança que você precisa em C ++ é a mudança foo para

void foo(int * & arr)

Uma vez que você está passando o ponteiro por valor, o ponteiro arr dentro principal é não apontar para a memória alocada. Isso significa duas coisas: você tem-se uma fuga de memória (NO, a memória não é liberada após o concluída função foo), e quando você acessar o ponteiro arr dentro principal que você está acessando alguns gama arbitrária de memória, portanto, você don 't obter 3 impresso e, portanto, free () se recusa a trabalhar. Você tem sorte de não obter uma falha de segmentação ao acessar arr [3] dentro principal.

Você não pode alterar o valor de seu argumento (arr) se não for aprovada no por referência (&). Em geral, você iria querer voltar o ponteiro, para que o seu método deve ser:

arr = foo ();

É ruim juju para tentar argumentos Reatribuir; Eu não recomendo a solução (&).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top