Ir ao conteúdo
  • Cadastre-se

C Alocação dinamica e ponteiro


giovany93

Posts recomendados

Eu estou tentando fazer um código em c no qual uma palavra deve ser criptografada.Eu não sei o que está dando errado.

#include<stdlib.h>
#include<string.h>
int main()
{
    int n;

    printf("DIGITE O TAMANHO DA PALAVRA...\n");
    scanf("%d",&n);
    char *p;
    p=(char*) malloc(n*sizeof(char));//aloco o valor digitado
scanf("%s",p);//armazeno na variável
printf(" %s",*p);//imprimo a palavra normalmente
    criptografia(*p,n);
}
void criptografia(char palavra[ ],int n)
{
    int i;
    for(i=0; i<n; i++)
    {
        switch(palavra)
        {
        case 'A':palavra='J';
        case 'B':palavra='K';
        case 'C':palavra='L';
        case 'D':palavra='M';
        case 'E':palavra='N';
        case 'F':palavra='O';
        case 'G':palavra='P';
        case 'H':palavra='Q';
        case 'I':palavra='R';
        case 'J':palavra='S';
        case 'K':palavra='T';
        case 'L':palavra='U';
        case 'M':palavra='W';
        case 'N':palavra='X';
        case 'O':palavra='Y';
        case 'P':palavra='Z';
        case 'Q':palavra='A';
        case 'R':palavra='B';
        case 'S':palavra='C';
        case 'T':palavra='D';
        case 'U':palavra='E';
        case 'V':palavra='F';
        case 'W':palavra='G';
        case 'X':palavra='H';
        case 'Y':palavra='I';
        case 'Z':palavra='J';

        }
    printf("%s",palavra);
    }

}

Link para o comentário
Compartilhar em outros sites

São alguns erros de sintaxe, principal é quando queremos acessar o endereço que é o "valor dentro de um ponteiro" usamos o nome do ponteiro sem asterisco. Mas quando queremos acessar o valor que está dentro do endereço "que é o valor de um ponteiro" usamos  asterisco. Com relação aos outros erros, são todos alertados pelo compilador. Assim com as devidas correções o seu programa fica assim:

#include  <stdio.h>  /**< inclui as funções padrões de entrada e saída. */ 
#include <stdlib.h>  /**< inlcui as funções manipuladoras de memória. */
#include <string.h>  /**< inclui as funções manipuladoras de strings. */

void criptografia (char palavra[], int n);

int main(int argc, char **argv){
    int n;
    printf ("DIGITE O TAMANHO DA PALAVRA...\n");
    scanf ("%d", &n);

    char *p;
    p =  (char*) malloc (n * sizeof(char) + 1);  /* aloco o valor digitado */
    scanf ("%s", p);  /* armazeno na variável */
    
    printf("original :: %s\n", p);  /* imprimo a palavra normalmente */

    criptografia (p, n);

    /* boa prática: limpe o contéudo, libere memória sem uso. */
    char *limit =  p - 1;
    p +=  n;
    while (limit  <--  p){ *p =  0; }
    
    free (p); 
 
    return  0; }


void criptografia (char palavra[], int n){
    int i;
    for (i =  0; i  <  n; i ++){
        switch (palavra[i]){
            case 'A':palavra[i] =  'J'; break;
            case 'B':palavra[i] =  'K'; break;
            case 'C':palavra[i] =  'L'; break;
            case 'D':palavra[i] =  'M'; break;
            case 'E':palavra[i] =  'N'; break;
            case 'F':palavra[i] =  'O'; break;
            case 'G':palavra[i] =  'P'; break;
            case 'H':palavra[i] =  'Q'; break;
            case 'I':palavra[i] =  'R'; break;
            case 'J':palavra[i] =  'S'; break;
            case 'K':palavra[i] =  'T'; break;
            case 'L':palavra[i] =  'U'; break;
            case 'M':palavra[i] =  'W'; break;
            case 'N':palavra[i] =  'X'; break;
            case 'O':palavra[i] =  'Y'; break;
            case 'P':palavra[i] =  'Z'; break;
            case 'Q':palavra[i] =  'A'; break;
            case 'R':palavra[i] =  'B'; break;
            case 'S':palavra[i] =  'C'; break;
            case 'T':palavra[i] =  'D'; break;
            case 'U':palavra[i] =  'E'; break;
            case 'V':palavra[i] =  'F'; break;
            case 'W':palavra[i] =  'G'; break;
            case 'X':palavra[i] =  'H'; break;
            case 'Y':palavra[i] =  'I'; break;
            case 'Z':palavra[i] =  'J'; break; }}

    printf ("criptografado :: %s\n", palavra);

    return  ; }

 

Link para o comentário
Compartilhar em outros sites

Ah sim , Eh verdade o ponteiro pode ser visto como vetor né? aih eu não preciso e nem posso fazer scanf("%s",*p);

Outra coisa você sabe me dizer porque quando digito a palavra (sem digitar o tamanho),o código não dah erro ?Por exemplo:

No código tá assim:

printf ("DIGITE O TAMANHO DA PALAVRA...\n"); scanf ("%d", &n);

mas se eu digitar qualquer palavra , o codigo já imprime a criptografia e a palavra normal ,porque não dah erro?

Queria saber mais coisa ainda...Aqui você aloca n+1 por causa do caracter do fim de string né? Se sim porque você não preenche a palavra?Ela eh automaticamente preenchida?

char *p; p = (char*) malloc (n * sizeof(char) + 1); /* aloco o valor digitado */ scanf ("%s", p); /* armazeno na variável */ printf("original :: %s\n", p); /* imprimo a palavra normalmente */ criptografia (p, n);

 

E aqui embaixo eu não entendi ,é que eu  sou "calouro em C"kkk.A função free já não faz essa limpeza.Me explique pfv ,pois eu não entendi o while nem char *limit = p - 1; p += n.Desde já agradeço!!!

 

/* boa prática: limpe o contéudo, libere memória sem uso. */ char *limit = p - 1; p += n; while (limit <-- p){ *p = 0; } free (p); return 0; }

Link para o comentário
Compartilhar em outros sites

20 minutos atrás, giovany93 disse:

Ah sim , Eh verdade o ponteiro pode ser visto como vetor né? aih eu não preciso e nem posso fazer scanf("%s",*p);

Sim.

 

21 minutos atrás, giovany93 disse:

Outra coisa você sabe me dizer porque quando digito a palavra (sem digitar o tamanho),o código não dah erro ?Por exemplo:

No código tá assim:

printf ("DIGITE O TAMANHO DA PALAVRA...\n"); scanf ("%d", &n);

mas se eu digitar qualquer palavra , o codigo já imprime a criptografia e a palavra normal ,porque não dah erro?

O espaço da memória que foi alocada para a variável n foi usado por outros programas anteriormente, logo provavelmente já existe um valor nesse espaço de memória, quando você digitou a palavra diretamente ao invés de um número a leitura do scanf falhou, e nenhum valor foi guardado na variável n, o que também significa que o valor que já estava lá não foi modificado.

 

Se esse valor for um número positivo grande o suficiente o seu programa vai funcionar, pois usa esse número para alocar a memória dinamicamente (como não se sabe o quão grande é o número possivelmente uma grande quantidade de memória é alocada), e o processo de criptografia funciona normalmente trabalhando nesse espaço de memória alocado. (Para evitar isso precisaria checar o retorno da função scanf para verificar se teve sucesso na leitura dos dados, e tomar decisões de acordo com o retorno.)

 

31 minutos atrás, giovany93 disse:

Queria saber mais coisa ainda...Aqui você aloca n+1 por causa do caracter do fim de string né? Se sim porque você não preenche a palavra?Ela eh automaticamente preenchida?

char *p; p = (char*) malloc (n * sizeof(char) + 1); /* aloco o valor digitado */ scanf ("%s", p); /* armazeno na variável */ printf("original :: %s\n", p); /* imprimo a palavra normalmente */ criptografia (p, n);

Sim, toda string em C acaba em um caractere nulo '\0', indicando onde a string acaba, logo o vetor de char deve ter pelo menos 1 posição a mais que o número de caracteres da string para poder armazenar o caractere nulo.

Mas não entendi sua dúvida, o que quer dizer com "porque você não preenche a palavra?" ? A palavra é fornecida pelo usuário no scanf("%s", p); .

 

36 minutos atrás, giovany93 disse:

E aqui embaixo eu não entendi ,é que eu  sou "calouro em C"kkk.A função free já não faz essa limpeza.Me explique pfv ,pois eu não entendi o while nem char *limit = p - 1; p += n.Desde já agradeço!!!

 

/* boa prática: limpe o contéudo, libere memória sem uso. */ char *limit = p - 1; p += n; while (limit <-- p){ *p = 0; } free (p); return 0; }

Sim, free() libera a memória, os valores continuam lá mas agora o espaço da memória pode ser usado para outras coisas e esses valores serão sobrepostos/substituídos. Nessa parte ele está zerando todas as posições da memória antes de desalocar a memória, mas também não entendi o porque isso seria necessário.

Link para o comentário
Compartilhar em outros sites

1 hora atrás, giovany93 disse:

E aqui embaixo eu não entendi ,é que eu  sou "calouro em C"kkk.A função free já não faz essa limpeza.Me explique pfv ,pois eu não entendi o while nem char *limit = p - 1; p += n.Desde já agradeço!!!

Certamente, a função desaloca a memória que foi alocada anteriormente, mas não faz a limpeza de seu conteúdo. Essa limpeza extra de seus valores antes de desalocar vai custar um pouco de desempenho do seu programa, que no contexto literalmente não significa nada, mais literalmente coletou-se o lixo com certeza.

 

 

 

 

 

19 minutos atrás, isrnick disse:

mas também não entendi o porque isso seria necessário.

Também quem lhe disse que é necessário. Você tem todo direito de não considera-la, mais não deve também distorce-la. E obrigado pelo restante!

Link para o comentário
Compartilhar em outros sites

Mas não entendi sua dúvida, o que quer dizer com "porque você não preenche a palavra?" ? A palavra é fornecida pelo usuário no scanf("%s", p);  Eu quero dizer se o caractere de fim de string é preenchido sozinho ou devemos fazer com que seja atribuída a última posição o '\0'.Outra coisa,eu entendei que a função limpa o espaço para depois desalocar,mas não entendi o código.

Link para o comentário
Compartilhar em outros sites

Em 15/08/2018 às 12:45, giovany93 disse:

Eu quero dizer se o caractere de fim de string é preenchido sozinho ou devemos fazer com que seja atribuída a última posição o '\0'.

Entendi.

 

Funções de leitura de string sempre colocam o '\0' após os caracteres de string automaticamente, não precisa fazer manualmente (certifique-se de que o vetor de caracteres que vai armazenar a string sempre seja grande o suficiente para armazenar todos os caracteres da string mais o caractere nulo '\0').

 

Obs: No caso do fgets() ele captura até o caractere nova linha '\n' que é digitado pelo usuário quando ele aperta Enter, então costuma-se remover manualmente esse caractere substituindo-o pelo caractere nulo '\0'.

 

Em 15/08/2018 às 12:45, giovany93 disse:

Outra coisa,eu entendei que a função limpa o espaço para depois desalocar,mas não entendi o código.

Funciona assim:

//Cria um ponteiro que aponta para uma posição de
//memória antes da posição apontada pelo ponteiro p:
char *limit =  p - 1;

//Faz p apontar para a posição final do vetor:
p +=  n;

//Vai decrementando 1 de p, e enquanto p for
//maior que a posição limite, coloca valor 0
//na posição do vetor.
while (limit  < --p){
    *p =  0;
}

free (p);

 

 

Mas @AnsiC agora que prestei atenção nesse código tem um problema pois p acaba com valor igual ao valor de limit, que é igual a p original menos 1, então free(p) vai estar liberando o lugar errado da memória. Certo?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...