Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

1. Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Apprentice X
ApprenticeX

(usa FreeBSD)

Enviado em 31/01/2023 - 22:28h

Boa Noite a todos

Não consigo entender abaixo, porque funciona de uma forma e da outra não, sendo que a função recebe o mesmo texto, e entendo que a função trata um ponteiro nas 2 situações, mas parece que ela está tratando as coisas completamente diferente, isso não consegui compreender!
#include <stdio.h>

void Change(char *Text) {
Text[5]= '\0';
puts(Text);
}

int main() {
char Text[]= "Slackware";
Change(Text);
Change("Slackware"); // Assim dá Segmentation fault
}



  


2. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 31/01/2023 - 22:29h

O código acima resulta em um Segmentation fault porque está se acessando um espaço de memória que não tem permissão para escrita. Isso ocorre porque na primeira chamada da função Change() o compilador cria uma váriável Text no stack frame, ou seja, o que está dentro da função já é um endereço de memória diferente do segundo argumento. Quando o compilador recebe o segundo argumento, ele está literalmente acessando a string "Slackware" e não um endereço de memória, de modo que tentando acessar a localização de memória e alterar a string não é possível, já que esta não pertence ao Stack Frame da função.


3. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 31/01/2023 - 22:36h

A alexabolada disse tudo dessa vez. Só vou completar com o seguinte:
int main() {
char Text[]= "Slackware";
Change(Text);
Change("Slackware"); // Assim dá Segmentation fault
}

A falha de segmentação acontece no segundo porque pelo que me lembro a string "Slackware" é uma constante pré alocada pelo compilador e isso significa que ela não pode ser usada para escrita, mas somente leitura.

Experimente trocar o change para esse código:
void Change(char *Text) {
puts(Text);
}

Vc verá que nada de mais acontece na segunda chamada, por quê?
Porque o Text sendo "Slackware" não foi modificado por nenhuma vez, nem pelo change nem pelo puts. Ou seja, a string constante do Text foi mantida inalterada na chamada e por isso não deu a falha de segmentação na escrita com Text[5] = '\0';

Já na primeira chamada, era uma área de memória não constante e válida na stack, como disse a alexa. E por isso, pode-se escrever e ler a vontade, dentro dos limites de memória, é claro.


https://nerdki.blogspot.com/ acessa ai, é grátis
Não gostou? O ícone da casinha é serventia do site!


4. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 31/01/2023 - 22:36h

{"id":"cmpl-6ewLTczH9VqcBMIXzUawMUdsbJxQV","object":"text_completion","created":1675215419,"model":"text-davinci-003","choices":[{"text":"","index":0,"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":911,"total_tokens":911}}



5. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Apprentice X
ApprenticeX

(usa FreeBSD)

Enviado em 31/01/2023 - 22:43h

alexabolada escreveu: O código acima resulta em um Segmentation fault porque está se acessando um espaço de memória que não tem permissão para escrita. Isso ocorre porque na primeira chamada da função Change() o compilador cria uma váriável Text no stack frame, ou seja, o que está dentro da função já é um endereço de memória diferente do segundo argumento. Quando o compilador recebe o segundo argumento, ele está literalmente acessando a string "Slackware" e não um endereço de memória, de modo que tentando acessar a localização de memória e alterar a string não é possível, já que esta não pertence ao Stack Frame da função.
Eu entendi e não entendi!

alexabolada escreveu: Isso ocorre porque na primeira chamada da função Change() o compilador cria uma váriável Text no stack frame
Não sei o que quer dizer com stack frame, penso que deve ser alguma área da memória

alexabolada escreveu: ou seja, o que está dentro da função já é um endereço de memória diferente do segundo argumento.
Entendo que o que está dentro da função seja a variável da própria função que claro acredito ser um endereço de memória diferente, mas isso para os 2 casos, visto que os 2 casos, enviam um texto para a variável da função, ou seja, porque é diferente o texto se os textos são iguais e representam-se iguais, ou seja o ponteiro da função aponta 1º para 1 e depois aponta para o outro local, a única diferença é o endereço de memória mas o valor de ambos são iguais.

alexabolada escreveu: Quando o compilador recebe o segundo argumento, ele está literalmente acessando a string "Slackware" e não um endereço de memória, de modo que tentando acessar a localização de memória e alterar a string não é possível, já que esta não pertence ao Stack Frame da função.
Aqui entendi sobre a string, mas penso, uma vez que a string foi enviada para o ponteiro da função, que é um ponteiro, ou seja, ele não recebe valor, ele recebe um endereço da memória onde foi alocada essa "STRING", logo dentro da função não existe String e sim um ponteiro apenas que está apontando para o endereço de memória onde está a String, e estou tentando mudar a posição para onde o ponteiro aponta, para então eu poder modificar o valor que está na memória.

Essa é a parte que ficou confusa!


6. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 31/01/2023 - 22:43h

Resposta:
De fato, estamos tentando acessar a memória de leitura e escrita onde a string "Slackware" foi alocada. No entanto, a memória não pertence ao Stack Frame da função e, portanto, é ilegal acessar essa área da memória. Por isso é que o código acima gera um Segmentation fault.

Essa chamada à função Change() criou uma variável chamada Text nos Stack Frames, ou seja, o endereço de memória dessa variável é diferente do endereço de memória onde a string "Slackware" foi armazenada. Quando o compilador recebeu o segundo argumento, ele está literalmente acessando a memória onde a string "Slackware" está armazenada, não a memória que pertence ao Stack Frame da função Change(), então a tentativa de acessar essa memória resultará em um Seg Fault. Para resolver esse problema, você pode copiar a string para a memória alocada usando memcpy () ou simplesmente passar um ponteiro para a string. Isso permitirá que você altere a string mesmo dentro da função.


7. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !?

Apprentice X
ApprenticeX

(usa FreeBSD)

Enviado em 31/01/2023 - 22:50h

SamL escreveu:A falha de segmentação acontece no segundo porque pelo que me lembro a string "Slackware" é uma constante pré alocada pelo compilador e isso significa que ela não pode ser usada para escrita, mas somente leitura.
Então isso significa que como o compilador quem alocou a string ele a bloqueou, impedindo que ela seja modificada.

Uma coisa que nunca reparei, visto que muitas vezes usamos "strings", mas também é um comportamento muito estranho e chato, pois muitas vezes enviamos algo para algum outro lugar.

Chato pq neste caso, eu teria que montar uma função muito diferente, ou seja, é mais seguro que dentro da função eu tenha um outro ponteiro que receba esse texto, pq não posso confiar no ponteiro da função, que pode receber um texto bloqueado.

Esquisito né?

#include <stdio.h>
#include <string.h> // strlen
#include <stdlib.h> // malloc

void Change(char *Text) {
// Alguém sabe fazer isso melhor? Não sei receber apenas o valor da função
// Todo o comentado abaixo deu errado! Só funciona a solução horrível que fiz abaixo

//char *Text_desbloqueado = *Text; // Deveria funcionar né?
//*Text_desbloqueado = *Text; // Deveria funcionar né? Segmentation fault
//char *Text_desbloqueado = Text;
//char *Text_desbloqueado = &Text;
//char Text_desbloqueado[strlen(Text) +1] = Text;
//char Text_desbloqueado[] = Text;
//strcpy(Text_desbloqueado, Text);
//strcpy(*Text_desbloqueado, Text);
//strcpy((char)*Text_desbloqueado, Text);
//strcpy(&Text_desbloqueado, Text);

// Única estranha e esquisita solução que achei
char *Text_desbloqueado = malloc(sizeof(Text));
memcpy(Text_desbloqueado, Text, sizeof(Text));

Text_desbloqueado[5] = '\0';
puts(Text_desbloqueado);
free(Text_desbloqueado);
}

int main() {
char Text[]= "Slackware";
Change(Text);
Change("Slackware"); // Assim dá Segmentation fault
}



8. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 31/01/2023 - 23:19h


ApprenticeX escreveu:

SamL escreveu:A falha de segmentação acontece no segundo porque pelo que me lembro a string "Slackware" é uma constante pré alocada pelo compilador e isso significa que ela não pode ser usada para escrita, mas somente leitura.
Então isso significa que como o compilador quem alocou a string ele a bloqueou, impedindo que ela seja modificada.

Uma coisa que nunca reparei, visto que muitas vezes usamos "strings", mas também é um comportamento muito estranho e chato, pois muitas vezes enviamos algo para algum outro lugar.

Chato pq neste caso, eu teria que montar uma função muito diferente, ou seja, é mais seguro que dentro da função eu tenha um outro ponteiro que receba esse texto, pq não posso confiar no ponteiro da função, que pode receber um texto bloqueado.

Esquisito né?

#include <stdio.h>
#include <string.h> // strlen

void Change(char *Text) {
// Não sei receber apenas o valor da função
//char *Text_desbloqueado = Text;
//char *Text_desbloqueado = *Text;
//char *Text_desbloqueado = &Text;
//char Text_desbloqueado[strlen(Text) +1] = Text;
//char Text_desbloqueado[] = Text;

Text_desbloqueado[5]='\0';
puts(Text_desbloqueado);
}

int main() {
char Text[]= "Slackware";
Change(Text);
Change("Slackware"); // Assim dá Segmentation fault
}

Cara, essas tuas dúvidas me desafiam meus conceitos sobre C. O que digo é, nunca vi em C alguém diferenciar um ponteiro const como "const char *" e exigir que se passe um ponteiro não const. No caso ali da segunda chamada, o ponteiro passado pra Change é um const char *, mas a função recebe um char * e é ai onde tu acha esquisito. Creio que deve haver opção de não compilar caso a chamada receba um const char *, porém, nada impede de fazer algo assim:
const char * distro = "Slackware";
char * ptr = distro;
Change(ptr);

Ali o Chnage não recebeu nenhum const char *, porém, a área apontada pelo ptr é um const char *, e vai dar o mesmo erro caso tente escrever dentro do ptr.

Acho que devido a liberdade com que o C trata os tipos dados, não dá pra ter muita certeza sobre os ponteiros, nem se onde um aponta é válido para escrita ou não.


https://nerdki.blogspot.com/ acessa ai, é grátis
Não gostou? O ícone da casinha é serventia do site!


9. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Apprentice X
ApprenticeX

(usa FreeBSD)

Enviado em 31/01/2023 - 23:36h

SamL escreveu:Cara, essas tuas dúvidas me desafiam meus conceitos sobre C. O que digo é, nunca vi em C alguém diferenciar um ponteiro const como "const char *" e exigir que se passe um ponteiro não const. No caso ali da segunda chamada, o ponteiro passado pra Change é um const char *, mas a função recebe um char * e é ai onde tu acha esquisito. Creio que deve haver opção de não compilar caso a chamada receba um const char *, porém, nada impede de fazer algo assim:
const char * distro = "Slackware";
char * ptr = distro;
Change(ptr);

Ali o Chnage não recebeu nenhum const char *, porém, a área apontada pelo ptr é um const char *, e vai dar o mesmo erro caso tente escrever dentro do ptr.

Acho que devido a liberdade com que o C trata os tipos dados, não dá pra ter muita certeza sobre os ponteiros, nem se onde um aponta é válido para escrita ou não.

O Ponto é mudar dentro da função, mas mesmo que eu declare a função com void Change(const char *Text) o problema persiste.

Não quero mudar no main, pq o main vai passar apenas um texto por escrito.
O texto real é esse: Search("xtx", "xt", "/mnt/values/");
Acontece que caso exista a / final, vou removê-la na função.

Para ter um código pequeno, eu não gostaria de ter que declarar uma variável, apenas pra passar o texto pra chamada de função, qdo o correto é ter o texto na própria chamada de função e funcionar.

Reflita:
   char Text[]= "Slackware"; // Bem feio assim né? 2 Linhas pra fazer o que 1 deveria fazer
Change(Text);
   Change("Slackware") // 1 Linha escrita, fica feio escrever 2 como o código acima 


Chato que mesmo a solução que encontrei mostrada no código acima dentro da função com memcpy e malloc ficou horrível também


10. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !? [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 31/01/2023 - 23:49h

Eu ainda não sei o que tu quer fazer, porque tipo, talvez teu código possa ser melhorado mas ainda assim talvez precise de alocar com malloc.
Me fala o que tu quer fazer? Bora pensar num modo mais otimizado possível de fazer a tarefa.


https://nerdki.blogspot.com/ acessa ai, é grátis
Não gostou? O ícone da casinha é serventia do site!


11. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !?

Apprentice X
ApprenticeX

(usa FreeBSD)

Enviado em 31/01/2023 - 23:54h

SamL escreveu:Eu ainda não sei o que tu quer fazer, porque tipo, talvez teu código possa ser melhorado mas ainda assim talvez precise de alocar com malloc.
Me fala o que tu quer fazer? Bora pensar num modo mais otimizado possível de fazer a tarefa.

Quero pegar o *Text da função, para desbloquear ele para edição! Como consigo pegar esse *Text para um novo ponteiro, ou mesmo para um char Text?

Pq nem isso consegui:

char Text_desbloqueado[] = Text;
char Text_desbloqueado[] = *Text;
char Text_desbloqueado[] = &Text;

Como coloco o Ponteiro da função que está bloqueado em qualquer variável que eu possa editar?
#include <stdio.h>

void Change(char *Text) {
// Quero acrescentar no máximo 1 linha aqui
Text_desbloqueado[5]= '\0';
puts(Text_desbloqueado);
}

int main() {
Change("Slackware");
}



12. Re: Função recebe 2 textos iguais, mas trata eles de forma diferente !?

Apprentice X
ApprenticeX

(usa FreeBSD)

Enviado em 01/02/2023 - 00:26h

Essa foi a solução menos deselegante que encontrei
#include <stdio.h>
#include <string.h>
// #include <stdlib.h>

void Change(char *Text) {
char Text_desbloqueado[strlen(Text) +1]; // Solução menos deselegante que encontrei pra desbloquear o texto do ponteiro *Text
strcpy(Text_desbloqueado, Text);

// Outra estranha e esquisita solução
//char *Text_desbloqueado = malloc(sizeof(Text));
//memcpy(Text_desbloqueado, Text, sizeof(Text));

Text_desbloqueado[5] = '\0';
puts(Text_desbloqueado);
//free(Text_desbloqueado);
}

int main() {
Change("Slackware");
}




01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts