¿Algún programador me pude decir por qué peta este pequeño código?

https://onlinegdb.com/BJPpaqH_m


Se supone que es porque tengo una variable apuntando a una dirección de memoria que no se puede cambiar su contenido por ser constante, ¿y al hacerlo peta? nunca lo he entendido.
¿Cuando dices que "te peta" exactamente cuánto ruido te hace? Porque no queda muy claro...

pd/ ¿qué variable? Si es el "hola mundo" dichoso...
No has compartido tu codigo
¿Por qué peta un hola mundo? :-?
Un puntero es una dirección de memoria, no un objeto. Al asignar A al puntero estás poniendo la dirección de memoria "A".
Tienes que modificar el contenido del puntero.
Reakl escribió:Un puntero es una dirección de memoria, no un objeto. Al asignar A al puntero estás poniendo la dirección de memoria "A".
Tienes que modificar el contenido del puntero.

¿Pero por qué no puedo cambiar ese caracter 'A' al que apunto por una 'B'?

Es decir, quiero que en la dirección de memoria 65 en vez de una 'A' haya una 'B'.
Veamos

#include <stdio.h>

int main()
{
    char *puntero=NULL;
    puntero = 'A';
   
    printf("%d",puntero);
   
   
    *puntero='B';
   
   
    return 0;
}


Primero, inicializas un puntero al valor 'A'. Pero A no es una cadena de texto, sino un caracter ascii, por lo que estas asignando el puntero a la posición 65 de la memoria, que probablemente no sea tuya.

Después imprimes el valor de ese puntero como entero, o sea imprimiras el 65.

Después adcedes a la posición 65 de la memoria para escribir, lógicamente el sistema operativo te manda a tomar por culo.

Snatcher10 escribió:
Reakl escribió:Un puntero es una dirección de memoria, no un objeto. Al asignar A al puntero estás poniendo la dirección de memoria "A".
Tienes que modificar el contenido del puntero.

¿Pero por qué no puedo cambiar ese caracter 'A' al que apunto por una 'B'?

Es decir, quiero que en la dirección de memoria 65 en vez de una 'A' haya una 'B'.

Porque estas trabajando en un sistema de memoria protegida (un ordenador). Toda memoria que quieras usar la tienes que reservar y el sistema operativo te dirá en que dirección tienes los bytes que has reservado.
@amchacon Lo de imprimirlo como entero lo hice a propósito porque me sonaba que ese caracter estaba siempre en la dirección de memoria 65. ¿no puedo reservar memoria en la direccion 65?
Snatcher10 escribió:
Reakl escribió:Un puntero es una dirección de memoria, no un objeto. Al asignar A al puntero estás poniendo la dirección de memoria "A".
Tienes que modificar el contenido del puntero.

¿Pero por qué no puedo cambiar ese caracter 'A' al que apunto por una 'B'?

Es decir, quiero que en la dirección de memoria 65 en vez de una 'A' haya una 'B'.


Ahí te has hecho un buen lío. En la dirección de memoria hay lo que haya.

primero tendrías que reservar una dirección de memoria para ti. Por ejemplo:

char caracter='A';


Esto te crea una variable con una dirección de memoria asociada. La que sea. Para acceder a esa dirección de memoria, usarías:

print("%c",carater); //Esto imprimiría A

char *direccion_caracter = &caracter;

print("%d",direccion_caracter);

*direccion_caracter='B';

print("%c",caracter); //Esto imprimiría B
Pero es que no has reservado memoria por ninguna parte.

Y el carácter no está siempre en una dirección concreta. Estás confundiendo el ASCII con la dirección de memoria
Crea una variable char por valor e inicializala con el valor A, y luego haces que el puntero apunte a su dirección de memoria:

char c='A';
puntero=&c;

No uses direcciones de memoria que el programa no tenga asignadas de antemano, la dirección 65 y todas las direcciones de memoria con números bajos están reservadas para el SO. Y cuando tu programa se ejecuta el sistema le reserva una zona de memoria en base a los datos y variables que use, si apuntas a una dirección no asignada a tu programa el sistema lo aborta.
Vale, lo que creo entender es que esa dirección de memoria ya estaba asignada de antemano por el SO, yo intento cambiar lo que hay en esa dirección de memoria y el SO no me lo permite.

@jorcoval
¿Y por qué me siempre me aparece el caracter A en la dirección de memoria 65?

https://conceptodefinicion.de/ascii/
El código ASCII para la A es 65, lo que no significa que esté en la dirección de memoria 65.
Snatcher10 escribió:Vale, lo que creo entender es que esa dirección de memoria ya estaba asignada de antemano por el SO, yo intento cambiar lo que hay en esa dirección de memoria y el SO no me lo permite.

@jorcoval
¿Y por qué me siempre me aparece el caracter A en la dirección de memoria 65?

https://conceptodefinicion.de/ascii/

No, no has asignado nada.
Para asignar memorita tienes que hacer un malloc:

char *c = malloc(sizeof(char));

esto reserva memoria y te devuelve la dirección de memoria donde se ha reservado.
Entonces ahora puedes acceder a esa memoria. Pero recuerda que un puntero guarda la dirección de memoria, no el contenido. Si quieres acceder al contenido, usas el asterisco:
*c = 'A';


Recuerda, char es un paquete de datos. char* es la dirección de memoria donde se aloja ese paquete.
Puedes acceder a la dirección de memoria de una variable ya creada con el &
char c = 'A'; //creamos variable
char* puntero_c = &c; //asignamos la dirección de memoria donde se encuentra la variable c al puntero
*puntero_c = 'B'; //cambiamos el contenido del puntero.


cuando creas una variable se asigna automaticamente una dirección de memoria, por eso no tienes que hacer un malloc si utilizas el puntero para apuntar a una dirección de memoria de una variable ya existente. con & devuelves esa dirección de memoria. Si la dirección de memoria no existe (no ha sido reservada por la aplicación), peta.

Pero eso ya es memoria dinámica, y hablamos de meternos en un berenjenal del quince.
El código ASCII lo que hace es una conversión de carácter a entero y viceversa, de tal forma que una variable int se puede almacenar en un char, pero no tiene nada que ver con las direcciones de memoria. Tú puedes inicializar un char con un int y el char luego muestra ese carácter:

char caracter=65;

printf("%c", caracter); // Esto devuelve la salida 'A'

Es de notar que no se han usado comillas simples en el ńumero, si fuera así se mostraría ese número tratado como char:

char caracter='6';

printf("%c", caracter); // Esto devuelve la salida '6'

@Reakl No es necesario que use malloc y memoria dinámica, eso sólo se debe usar cuando se trabaja con arrays y grandes estructuras de datos de las que no se conocen sus dimensiones de antemano o estas varían en tamaño durante la ejecución del programa. El sistema ya reserva memoria de antemano para las variables estáticas. Además para empezar a meterse en memoria dinámica todavía le queda, primero hay que dominar los punteros.
@coyote-san Tengo aprobada fundamentos de programación y programación orientada a objetos hace muchos años con bastante buena nota aunque sea difícil de creer xD, estoy refrescando la memoria, pero siempre de estudiante tuve esa duda de noob.
@coyote-san Cierto, pero le veo con un cacao mental con lo que es una dirección y un dato.
coyote-san escribió:
@Reakl No es necesario que use malloc y memoria dinámica, eso sólo se debe usar cuando se trabaja con arrays y grandes estructuras de datos de las que no se conocen sus dimensiones de antemano o estas varían en tamaño durante la ejecución del programa.

Hombre, algunos casos más en los que hay que usarla :p
@jorcoval Bueno sí, pero para el problema del compañero no es necesario vamos, el resultado sería casi el mismo que declarar la variable como estática y no merece la pena reservar memoria con malloc para un char.
@jorcoval Y cómo sacarías la dirección de memoria del caractar A?
@Snatcher10 Esa pregunta no tiene sentido, compañero. Creo que necesitas refrescar conceptos con algún libro de texto.
Snatcher10 escribió:@jorcoval Y cómo sacarías la dirección de memoria del caracter A?

No hay ninguna dirección de memoria.

Si haces:
int c = 'A';


El compilador transforma tu 'A' por un 65.
Snatcher10 escribió:@jorcoval Y cómo sacarías la dirección de memoria del caractar A?

Es que hablas de "el carácter A" como si estuviese escrito a fuego siempre en un mismo sitio. Y no es así.

Como te ha apuntado antes un compañero:

Sí haces
char c='A';

Entonces en &c tienes la dirección de memoria donde has guardado el carácter A de ese programa.

Es más, matas al programa, vuelves a ejecutarlo y casi seguro que dicha dirección ha cambiado.
amchacon escribió:
Snatcher10 escribió:@jorcoval Y cómo sacarías la dirección de memoria del caracter A?

No hay ninguna dirección de memoria.

Si haces:
int c = 'A';


El compilador transforma tu 'A' por un 65.

La variable c declarada como entero tiene una dirección de memoria, ok. ¿Y el caracter A (y el resto de ellos) no tienen asignados una dirección de antemano?

edit: Menuda gilipollez estoy preguntando [facepalm]
Snatcher10 escribió:[ ¿Y el caracter A (y el resto de ellos) no tienen asignados una dirección de antemano?

edit: Menuda gilipollez estoy preguntando [facepalm]

Confundes el valor ASCII con la dirección en memoria de una variable.

La dirección en memoria es el cajón de una cajonera. El carácter A es lo que metes en ese cajón.

No puedes intentar localizar algo que todavía no tienes dentro XD
No, no tienen una dirección preasignada, ni declarada de antemano.

La tiene el número 4000?
El carácter +?
jorcoval escribió:No, no tienen una dirección preasignada, ni declarada de antemano.

La tiene el número 4000?
El carácter +?

Sí, caí después de haberlo escrito [reojillo] Tengo que refrescar conceptos.

Muchas gracias a todos por vuestra paciencia y ayuda [beer] , un saludo!
27 respuestas