Poste o código, sem ele fica difícil analisar.
#include<stdio.h>
int main(){
char *str1 = "b";
char *str2 = "b";
printf("%c\n%c\n\n\n",*str1,*str2);
printf("%d, %d\n", &str1, &str2);
system("pause");
return 0;
}
Citando e comentando seu código:
#include<stdio.h>
int main(){
char *str1 = "b";
char *str2 = "b";
printf("%c\n%c\n\n\n",*str1,*str2); // aqui está você imprimindo dois caracteres iguais. OK
printf("%d, %d\n", &str1, &str2); // aqui está você imprimindo dois endereços DE ponteiros... O que novamente não tem absolutamente nada a ver com minha pergunta hehe
system("pause");
return 0;
}
str1 e str2 já são ponteiros em si. Teste com elas sem o & comercial e compare o resultado.
2 operadores unários são usados:
----- &: obtém o endereço de memória de uma variável
----- *: obtém o conteúdo do endereço de memória armazenado em um ponteiro
Agora eu entendi, hehe, prometo trazer a resposta, se não aparecer antes
[]'s
[quote=getAdicted]2 operadores unários são usados:
----- &: obtém o endereço de memória de uma variável
----- *: obtém o conteúdo do endereço de memória armazenado em um ponteiro
[/quote]
Veja bem, amigo. Não confunda as coisas.
Eu jamais neguei isso.
Mas str1 e str2 já tratam de endereços, compreende?
Se não fossem, nem faria sentido vc usar *str1 ou *str2.
Agora, quando você usa &str1 ou &str1, vc obtém o endereço de memória de OUTRO endereço de memória, não percebe?
No tópico em questão estamos comparandos os endereços str1 e str2, não o edereços dos endereços . hehe
Se tratam sobre endereços tenho lá minhas dúvidas, mas será que eles tratam sobre posição? Talvez eles possam assumir tamanhos parecidos na memória, exemplo: *str1=1082144 até 1082148 == *str2 = 1082144 até 1082148. Sinceramente não sei como funciona.
… é pegadinha veia essa hein mano, hehe
Se tratam sobre endereços tenho lá minhas dúvidas, mas será que eles tratam sobre posição, talvez eles possam assumir tamanhos parecidos na memória, exemplo: *str1=1082144 até 1082148 == *str2 = 1082144 até 1082148. Sinceramente não sei como funciona.[/quote]
str1 e str2 referenciam a mesma posição de memória.
A questão é: COMO PODE?
é coisa do demonio!
ai cake, ce tem parte com o capeta rapa… kkkk
brincadeira…
O motivo é exatamente o mesmo do Java.
Existe um pool de strings literais, que fica gravado na área de dados do processo. Portanto, duas literais com o mesmo valor (ou seja, strings criadas com aspas) irão ocupar o mesmo endereço de memória, pois o compilador irá reaproveita-las desse pool.
char* um = "valor";
char* dois = "valor";
O endereço de um e dois será o mesmo.
Para alterar essa situação, você deve criar os chars como arrays:
char[6] um = "valor";
char[] dois = "valor";
Pois aí o C garantirá a reserva do vetor de char e sua cópia. É também o motivo pelo qual após fazer:
char* teste = "Vanicius";
teste[1] = 'i';
Você pode dar pau, já que o seguimento de memória do buffer de strings é read-only.
Para mais informações, veja o item 6.4.5 do standard:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n897.pdf
[i]"String literals are not required to be modifiable. This specification allows implementations to share copies of strings with identical text, to place string literals in read-only memory, and to perform certain optimizations. However, string literals do not have the type array of const char in order to avoid the problems of pointer type checking, particularly with library functions, since assigning a pointer to const char to a plain pointer to char is not valid. Those members of the C89 Committee
who insisted that string literals should be modifiable were content to have this practice designated a common extension (see §K.5.5).
Existing code which modifies string literals can be made strictly conforming by replacing the string
literal with an initialized static character array."[/i]
Esse tópico faz engenharia reversa para comparar as duas abordagens:
Ce manja mto, Vini!
Quando crescer quero ser q nem vc! =p
Brigadão!
[quote=cake]Ce manja mto, Vini!
Quando crescer quero ser q nem vc! =p[/quote]
E eu que nem o Thingol e o Entanglement…
Muito bem colocado Vinicius, eu consegui essa informação hoje pela manhã, eu ia postar, mas como você já o fez, meus trabalhos não serão mais necessários.
Se eu postar uma dúvida aqui, você poderia fazer a gentileza de olhar?
http://www.guj.com.br/posts/list/224200.java
Gostaria de um exemplo que utiliza essa modalidade de arquitetura.
Obrigado!
[]'s
Bom… Foi esclarecido que o C armazena as strings literais em um pool read only.
Então, estive pensando…
Ao declarar:
“esquilo” ocupará o pool para sempre?
Não há um coletor para apagá-lo caso eu anule e, há?
Sim.
Não, não existe. Garbage collection é coisa do java, heheheeh.
Agora, note que o standard permite que a implementação ou não de um pool fique a cargo do fabricante do compilador. Provavelmente compiladores para dispositivos mais humildes não terão esse recurso ou, no mínimo, terá uma flag para tornar isso opcional.
E note também que isso só vale para literais, que geralmente ocupam pouco espaço mesmo.
Dependendo do compilador (e até das opções de compilação), o lugar onde são guardadas strings literais pode estar em um segmento de memória apenas de leitura ou então que pode ser lido e escrito.
No caso do Microsoft Visual C++, a opção /GF (“enable read-only string pooling”) controla isso.
No caso do gcc, por causa de um recurso muito interessante (ele verifica se é possível combinar constantes strings, e se puder fazer isso, as combina), ele sempre tenta pôr em um pool read-only, já que senão você teria problemas mais graves que no Visual C++ (onde você, em tese, só estragaria uma constante, não um monte como poderia ser o caso do gcc).
Pelo que está escrito (não tenho um gcc aqui para confirmar), se você tivesse as seguintes strings:
char *nome1 = “Oliveira”;
char *nome2 = “Aparecido de Oliveira”;
char *nome3 = “José Aparecido de Oliveira”;
o gcc poderia guardar espaço apenas para “José Aparecido de Oliveira”, e fazer nome2 apontar para a posição dessa string que contém “Aparecido de Oliveira”, e nome3 apontar para “Oliveira”.
Então, se você mudasse a letra "v’ em nome1 para ‘b’, você teria nome1 = “Olibeira”, nome2 = “Aparecido de Olibeira”, e nome3 = “José Aparecido de Olibeira”. Obviamente isso é uma fonte infindável de bugs, portanto ele deve é deixar a string em um segmento read-only; nesse caso, o programa iria tomar uma exceção (ou um SIGBUS) quando fosse tentar mudar a letra ‘v’.
Ouvi dizer que alguns compiladores tem otimizações na std::string para se aproveitar de pools como esse. E no caso da std::string é ainda mais eficiente, já que ela não termina em \0. Então, no caso acima, a String “José” também compartilharia a área de José Aparecido de Oliveira.
Agora, não me recordo de cabeça se isso foi só um autor comentando da possibilidade, ou se tem algum compilador comercial implementado com o recurso.
Esse esquema de pool de strings é bem interessante.