Estou desenvolvendo um trabalho para faculdade e encontrei um problema que não consigo resolver.
Seguinte:
1 - Preciso criar uma função que gere um vetor de N elementos, sendo N dado por size;
2- Criada a função, preciso que esse vetor seja retornado para posteriormente ser trabalhado;
No código abaixo ilustrei que o vetor que vai receber 5 valores (0 a 4) de 10, em todos os índices, porém quando executo o código, somente o valor do primeiro índice é exibido corretamente e os demais são endereços de memoria do computador.
Segue o código de ilustração do meu problema:
#include <stdio.h> #include <stdlib.h>
int *vet(int size);
int main(){
int *ptr;
int size = 4;
ptr = vet(size);
for(int i = 0; i <= size; i++){
printf("\n%d", ptr[i]);
}
}
int *vet(int size){
int *p;
int vet[size];
p = vet;
for(int i = 0; i <= size; i++){
vet[i] = 10;
}
return p;
}
O problema é o escopo do seu vetor. Quando você aloca estaticamente um vetor ele tem escopo local, isso é, ele só é válido enquanto você está dentro da função. Quando você sai da função essa área de memória será automaticamente liberada. Nesse caso você tem duas opções:
Você aloca o vetor globalmente, ou na função principal, e passa o ponteiro como argumento para a função
Você aloca o vetor dinamicamente com calloc(size, sizeof(int)), lembrando de liberar a memória com free() depois de usar os dados
Olá amigo, boa tarde e obrigado pela pronta resposta !
Inda estou com dificuldade, não tenho muita experiencia com alocação em C, mas me corrija se estiver errado:
#include <stdio.h>
#include <stdlib.h>
int *vet(int size);
int main(){
int *ptr;
int size = 4;
ptr = vet(size);
for(int i = 0; i <= size; i++){
printf("\n%d", ptr[i]);
}
}
int *vet(int size){
int *p = (calloc(size, sizeof(int)));
int vet[size];
for(int i = 0; i <= size; i++){
vet[i] = 10;
}
p = vet;
p.free();
return p;
}
#include <stdio.h>
#include <stdlib.h>
int* vet(int, int);
int main(int argc, char** argv) {
int tamanho = 4;
int valorInicial = 10;
int* ptr = vet(tamanho, valorInicial);
for (int i = 0; i < tamanho; i++)
printf("Valor na posicao %d: %d\n", i, ptr[i]);
free(ptr);
}
int* vet(int tamanho, int valorInicial) {
int *ptr = malloc(tamanho * sizeof(int)); // aqui você deve alocar memória na heap, e não na stack, para que ela possa ser acessada em outro escopo
for (int i = 0; i < tamanho; i++)
ptr[i] = valorInicial;
return ptr;
}
O argumento que a função malloc recebe a quantidade de bytes que devem ser alocados. Um int tem geralmente 4 ou 8 bytes, dependendo da arquitetura do computador.
Por isso, você tem que colocar malloc(tamanho * sizeof(int)), pois a função sizeof retorna o tamanho em bytes de um tipo.
Se você quer um vetor de ints com tamanho 10, e um int no teu computador tem o tamanho 8, você precisa alocar 80 bytes para guardar os 10 ints. Sacou? Sem levar em conta o tamanho do int, você está alocanco só 10 bytes! A consequência disso é indeterminada. As vezes vai funcionar, as vezes vai dar segmentation fault.
Tá certo! Você também pode usar a função calloc, como o @rmendes08 citou. É um pouquinho diferente, e pode ser mais eficiente (por uma série de motivos de alocação e como as chamadas de sistema são feitas).
A diferença principal, sem falar de performance, é que o calloczera todos os bytes do array. Ou seja, vai vir tudo 0. O malloc não zera, vem do jeito que estava antes. Tem uma série de questões como o sistema operacional aloca memória para o processo, de segurança e tals, mas você pode pensar dessa maneira: o malloc pode realocar alguma memória que teu programa já usou antes e liberou, por isso, pode vir com lixo.
Você recomendaria algum livro ou material a respeito de alocação de memoria ? Creio que é um assunto complexo e de difícil assimilação, porém essencial para o desenvolvimento a baixo nível.
Cara, se você pegar um livro de sistemas operacinais bom, como o do Tanenbaum, você vai aprender bastante sobre como funciona um processo e como ele interage com o kernel através das chamadas de sistema. Porém, eu não acho que isso seja extremamente relevante nesse momento que você está começando, vai ofuscar mais do que ajudar. É só minha opinião, quem sou eu para dizer oq vc deve ou não estudar? Kkkkkk
Com certeza é uma leitura ótima e vai te tornar um programador melhor, mas eu diria para você se concentrar mais nos mecanismos da linguagem. Basta saber que malloc, calloc, e realloc fazem a mágica da alocação pra ti!
Acho que o que você precisa aprender além de como usar as funções, é ponteiros. A forma de gerenciamento de memoria muda de linguagem para linguagem, agora o conceito de ponteiros é algo que existe em todas, sendo que em algumas como C isso é mais explicito e em outras não, mas independente é um conceito fundamental de entender.