una toshiba tiene tengo saber que puede para pagina memoria maximo lenovo laptop externa cuanto cuanta como cambiar aumentar c string pointers malloc const

c - toshiba - pagina para saber que memoria ram tengo



Cuando asignar memoria a char* (7)

Funcionará bien, pero el compilador puede recibir una advertencia porque apunta a una cadena constante.

PD: se ejecutará correctamente solo cuando no lo estés modificando. Entonces, la única desventaja de no usar malloc es que no podrá modificarlo.

Estoy un poco confundido cuando asignar memoria a un char * y cuando apuntarlo a una cadena constante.

Sí, entiendo que si deseo modificar la cadena, necesito asignarla memoria.

Pero en los casos en los que no deseo modificar la cadena a la que apunto y solo necesito pasar el valor, ¿debo hacer lo siguiente? ¿Cuáles son las desventajas en los pasos a continuación en comparación con la asignación de memoria con malloc ?

char *str = NULL; str = "This is a test"; str = "Now I am pointing here";


Intentemos nuevamente su ejemplo con el -Wwrite-strings advertencia del compilador de -Wwrite-strings , verá una advertencia:

warning: initialization discards ''const'' qualifier from pointer target type

Esto se debe a que el tipo de "Esto es una prueba" es const char * , no char * . Por lo tanto, está perdiendo la información de constness cuando asigna la dirección literal al puntero.

Por razones históricas, los compiladores le permitirán almacenar literales de cadena que son constantes en variables no constantes.

Este es, sin embargo, un mal comportamiento y le sugiero que use -Wwrite-strings todo el tiempo.

Si quieres probarlo por ti mismo, intenta modificar la cadena:

char *str = "foo"; str[0] = ''a'';

Este comportamiento del programa no está definido, pero es posible que vea una falla de segmentación en muchos sistemas. Ejecutando este ejemplo con Valgrind , verás lo siguiente:

Process terminating with default action of signal 11 (SIGSEGV) Bad permissions for mapped region at address 0x4005E4

El problema es que el binario generado por su compilador almacenará los literales de cadena en una ubicación de memoria que es de solo lectura . Al intentar escribir en él, se produce un fallo de segmentación .

Lo que es importante entender es que se trata de dos sistemas diferentes:

  1. El sistema de escritura en C, que es algo que te ayuda a escribir el código correcto y se puede "silenciar" fácilmente (mediante el lanzamiento, etc.)

  2. Los permisos de la página de memoria del Kernel que están aquí para proteger su sistema y que siempre se respetarán.

Nuevamente, por razones históricas, este es un punto donde 1. y 2. no están de acuerdo. O, para ser más claro, 1. es mucho más permisivo que 2. (lo que hace que el programa sea eliminado por el núcleo).

¡No te dejes engañar por el compilador, los literales de cadena que estás declarando son realmente constantes y no puedes hacer nada al respecto!

Teniendo en cuenta que tu puntero str lee y escribe está bien. Sin embargo, para escribir el código correcto, debe ser un const char * y no un char * . Con el siguiente cambio, su ejemplo es una pieza válida de C:

const char *str = "some string"; str = "some other string";

( const char * puntero a una cadena const)

En este caso, el compilador no emite ningún aviso. Lo que escriba y lo que estará en la memoria una vez que se ejecute el código coincidirá.

Nota: un puntero de const a una cadena const char *const :

const char *const str = "foo";

La regla de oro es: ser siempre lo más constante posible.

Si necesita modificar la cadena, use la asignación dinámica (malloc () o mejor, alguna función de manipulación de cadenas de nivel superior como strdup, etc. de la libc), si no es necesario, use una cadena literal.


No hay ningún problema en su código siempre y cuando no esté planeando modificar el contenido de esa cadena. Además, la memoria de dichos literales de cadena permanecerá durante toda la vida útil del programa. La memoria asignada por malloc es de lectura y escritura , por lo que puede manipular el contenido de esa memoria.


Si sabe que str siempre será de solo lectura, ¿por qué no declararlo como tal?

char const * str = NULL; /* OR */ const char * str = NULL;

Bueno, en realidad hay una razón por la que esto puede ser difícil: cuando se pasa la cadena a una función de solo lectura que no se declara como tal. Supongamos que está utilizando una biblioteca externa que declara esta función:

int countLettersInString(char c, char * str); /* returns the number of times `c` occurs in `str`, or -1 if `str` is NULL. */

Esta función está bien documentada y usted sabe que no intentará cambiar la cadena de caracteres, pero si la llama con una cadena constante, ¡su compilador podría avisarle! Sabes que no hay nada peligroso en ello, pero tu compilador no lo hace.

¿Por qué? Debido a que en lo que concierne al compilador, tal vez esta función intente modificar el contenido de la cadena, lo que causaría que su programa se bloquee. Tal vez usted confía mucho en esta biblioteca y hay muchas funciones que se comportan así. Entonces, tal vez sea más fácil no declarar la cadena como const en primer lugar, pero depende de usted asegurarse de no intentar modificarla.

Por otro lado, si usted es el que escribe la función countLettersInString , simplemente asegúrese de que el compilador sepa que no modificará la cadena declarándola con const :

int countLettersInString(char c, char const * str);

De esta forma aceptará cadenas constantes y no constantes sin problema.


Si tiene una cadena literal que no desea modificar, lo que está haciendo es correcto:

char *str = NULL; str = "This is a test"; str = "Now I am pointing here";

Aquí, un puntero tiene una memoria a la que apunta. En la segunda línea escribe en esa memoria "This is a test" y luego nuevamente en 3 líneas escribe en esa memoria "Now I am pointing here" . Esto es legal en C.

Puede que le resulte un poco contradictorio pero no puede modificar una cadena que es algo así:

str[0]=''X'' // will give a problem.

Sin embargo, si desea poder modificarlo, utilícelo como un búfer para mantener una línea de entrada y así sucesivamente, use malloc :

char *str=malloc(BUFSIZE); // BUFSIZE size what you want to allocate free(str); // freeing memory

Use malloc() cuando no sepa la cantidad de memoria necesaria durante el tiempo de compilación.


Una desventaja de usar cadenas-literales es que tienen restricciones de longitud. Por lo tanto, debe tener en cuenta el documento ISO / IEC: 9899 (énfasis mío)

5.2.4.1 Límites de traducción

1 La implementación deberá poder traducir y ejecutar al menos un programa que contenga al menos una instancia de cada uno de los siguientes límites:

[...]

- 4095 caracteres en un literal de cadena de caracteres o literal de cadena ancha (después de la concatenación)

Por lo tanto, si su texto constante supera este recuento (lo que algunas veces puede ser posible, especialmente si escribe un servidor web dinámico en C), tiene prohibido utilizar el método de cadena literal si desea permanecer independiente del sistema.


Desafortunadamente , es legal en C, pero cualquier intento de modificar el literal de la cadena a través del puntero resultará en un comportamiento indefinido .

Decir

str[0] = ''Y''; //No compiler error, undefined behavior