Malloc dentro de uma chamada de função parece estar sendo libertado em troca?
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.
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 (&).