¿Por qué se puede asignar una cadena a un puntero char*, pero no a un char?[] ¿formación?

6 minutos de lectura

¿Por que se puede asignar una cadena a un puntero
mella

¿Alguien puede explicar por qué esto funciona con el puntero?

char * str1;

str1 = "Hello1";

str1 = "new string";

// but not this
char str2 [] = "hello";
str2 = "four";

// or this
char str3 [];
str3 = "hello";
str3 = "hello";

  • Esta pregunta cubre el mismo terreno, solo que está redactada de manera diferente. No estoy seguro de si esto es lo suficientemente duplicado para cerrar, pero se aplican las respuestas allí.

    – Tim Publicar

    24 de julio de 2011 a las 3:17

  • @Tim Post: la supuesta pregunta duplicada y su respuesta en mi opinión no están relacionadas con esta pregunta porque esta pregunta cosas en tiempo de compilación, la otra pregunta cosas en tiempo de ejecución

    – Armen Tsirunyan

    24 de julio de 2011 a las 10:48


1646759295 269 ¿Por que se puede asignar una cadena a un puntero
pruebaurbest

Por qué funciona con punteros:

Cuando tu dices char * str1 en C, está asignando un puntero en la memoria. Cuando escribes str1 = "Hello";, está creando un literal de cadena en la memoria y haciendo que el puntero apunte hacia él. Cuando creas otro literal de cadena "new string" y asignarlo a str1todo lo que está haciendo es cambiar el lugar donde apunta el puntero.

Por qué no funciona con matrices:

Cuando tu dices char str2 [] = "Hello", está creando un literal de cadena y colocándolo en la matriz durante su definición. Está bien no dar un tamaño, ya que la matriz lo calcula y agrega un '\0' lo. No puede reasignar nada a esa matriz sin cambiar su tamaño. Es por eso que str2 = "four" no trabajará.

En caso de str3, es el mismo caso. No ha definido el tamaño de la matriz en la definición, por lo que calculó que su tamaño era 0. No puede asignar nada nuevo sin cambiar el tamaño de la matriz.

  • Saludos, TryUrBest. La mayoría de los libros de C que he visto dan mucha importancia a las cadenas, los punteros y las matrices. En el caso de str1 (el puntero), ¿es esa la forma de hacerlo? Deje de preocuparse por “lo estoy haciendo 100% correcto” y simplemente haga punteros a las cadenas y utilícelos como lo hice anteriormente. Dijiste que el primer método mueve el puntero, es el orig. datos destruidos entonces, o es una fuga?

    – mella

    24 de julio de 2011 a las 6:03

  • @tryurbest: ¿puedo agregar más preguntas? en caso de usar char* str=”alguna cadena”, ¿se considera que esta cadena es una cadena de tamaño fijo? Si más adelante, este puntero se procesa para agregar más cadenas. ¿Eso generará una violación de acceso a la memoria? ¡Gracias! en realidad, lo he probado y veo el error. Pero no estoy seguro acerca de la parte “cadena de tamaño fijo” o “cadena constante” allí

    – TSL_

    29 de noviembre de 2014 a las 3:08


  • Qué sucede con la cadena anterior “Hola”. ¿Es esto hay memoria y contribuye a la fuga de memoria? O que se libera automáticamente?

    – Jon Wheelock

    11 de octubre de 2015 a las 2:05

  • Según KN King, en su segundo ejemplo char str2 [] = “Hola”, aunque “Hola” parece ser una cadena literal, no lo es. En cambio, C lo ve como una abreviatura de un inicializador de matriz.

    – ilstam

    17 de junio de 2017 a las 19:24

Una matriz y un puntero son cosas diferentes, por eso. Puede asignar a un puntero, pero no puede asignar a una matriz. Se hace una excepción especial para la inicialización de matrices de caracteres con literales de cadena.

char a[] = "Hello"; //initialize a char array with string literal. Special case, OK
char* p = "Hello"; //initializa a pointer with an array(which gets converted to pointer)
p = "My";   //assign pointer to point to another value. OK
a = "My";   //error, arrays cannot be assigned to. Use `strcpy`

Los literales de cadena (como “Hola”) tienen tipo char[N] donde N es el número de caracteres (incluida la terminación '\0'). Una matriz se puede convertir en un puntero a su primer elemento, pero las matrices y los punteros no son lo mismo, digan lo que digan algunos libros o maestros malos.

  • no olvides const como un problema aquí.

    – Cachorro

    23 de julio de 2011 a las 21:28

  • @DeadMG: AFAIK en los literales de cadena C no son const char [N]. Ellos son char [N]. Es por eso que (solíamos) tener la conversión implícita a char* de literales de cadena en C++. ¿Me equivoco?

    – Armen Tsirunyan

    23 de julio de 2011 a las 21:30


  • @Armen: No, oficialmente no lo son const char[N], pero en realidad, muy a menudo lo son. La mayoría de los compiladores colocan literales de cadena en la memoria de solo lectura. Eso significa que el usuario generalmente no debe intentar hacer *p = 'A';.

    – Rudy Velthuis

    23 de julio de 2011 a las 21:39

  • @Rudy: independientemente de dónde el compilador mantenga un literal de cadena, haciendo *p = 'A' tiene un comportamiento indefinido, que en mi opinión es irrelevante para la pregunta del OP. Pero el tipo de un literal de cadena es (desafortunadamente) solo char[N] C ª.

    – Armen Tsirunyan

    23 de julio de 2011 a las 21:44

  • OK Chicos, gracias. Armen hizo un muy buen punto. He leído que los punteros y las matrices son básicamente lo mismo.

    – mella

    24 de julio de 2011 a las 5:50

En pocas palabras, porque una matriz no es un objeto de primera clase en C/C++. La única forma de asignar a una matriz es usar str(n)cpy o memcpy.

Si bien una matriz se colapsa en un puntero cuando se pasa a una función, no es posible asignarla a una matriz, excepto en tiempo de compilación como inicialización.

1646759296 717 ¿Por que se puede asignar una cadena a un puntero
Sawan

Es simplemente porque, cuando escribes este código:

char str2 [] = "hello";

o incluso:

int arr[] = {1,2,4,4,5};

crea str2 o arr como puntero constante. Es por eso que no puede reasignar ningún otro valor a estos punteros, mientras que en un caso posterior está creando un puntero normal y puede asignarle cualquier cosa.

El caso de los punteros
Funciona porque cuando estás asignando como str1="Hello" , en realidad está creando un literal de cadena llamado hola, asignándolo en algún lugar de la memoria y asignando la dirección del primer carácter del literal al puntero, y como el puntero no es constante, puede asignarlo nuevamente con diferentes direcciones. Y un punto más importante a tener en cuenta es que el literal de cadena creado está en la memoria de solo lectura.

El caso con matriz de caracteres
Puede asignarle un literal de cadena durante la inicialización, ya que es compatible con el idioma. Y no confunda la asignación con la inicialización. Durante la asignación, dado que es una matriz de caracteres, debe cambiar el valor carácter por carácter. Está tratando de dirigir la primera dirección de la cadena literal al primer carácter de la matriz (el nombre de la matriz devuelve la dirección del primer elemento de la matriz). Y esto claramente no es correcto ya que el primer elemento no es un puntero, no puede almacenar la dirección.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad