Almacenamiento para strings en C

En C, se puede hacer referencia a una string mediante un puntero de carácter o como una array de caracteres. 
Strings como arrays de caracteres  

C

char str[4] = "GfG"; /*One extra for string terminator*/
/*    OR    */
char str[4] = {‘G’, ‘f’, ‘G’, '\0'}; /* '\0' is string terminator */

Cuando las strings se declaran como arrays de caracteres, se almacenan como otros tipos de arrays en C. Por ejemplo, si str[] es una variable automática , la string se almacena en el segmento de la pila, si es una variable global o estática, se almacena en el segmento de datos. , etc.

Strings que usan punteros de caracteres 
El uso de strings de punteros de caracteres se puede almacenar de dos maneras:

1) String de solo lectura en un segmento compartido. 
Cuando un valor de string se asigna directamente a un puntero, en la mayoría de los compiladores, se almacena en un bloque de solo lectura (generalmente en un segmento de datos) que se comparte entre funciones. 

C

char *str  =  "GfG";  

En la línea anterior, «GfG» se almacena en una ubicación compartida de solo lectura, pero el puntero str se almacena en una memoria de lectura y escritura. Puede cambiar str para señalar otra cosa, pero no puede cambiar el valor en la str actual. Por lo tanto, este tipo de string solo debe usarse cuando no queremos modificar la string en una etapa posterior del programa.

2) Asignado dinámicamente en el segmento de almacenamiento dinámico. 

Las strings se almacenan como otras cosas asignadas dinámicamente en C y se pueden compartir entre funciones. 

C

char *str;
int size = 4; /*one extra for ‘\0’*/
str = (char *)malloc(sizeof(char)*size);
*(str+0) = 'G'; 
*(str+1) = 'f';  
*(str+2) = 'G';  
*(str+3) = '\0';  

Veamos algunos ejemplos para comprender mejor las formas anteriores de almacenar strings.

Ejemplo 1 (Intentar modificar la string) 
El siguiente programa puede bloquearse (da un error de falla de segmentación) porque la línea *(str+1) = ‘n’ intenta escribir una memoria de solo lectura. 

C

int main()
{
 char *str; 
 str = "GfG";     /* Stored in read only part of data segment */
 *(str+1) = 'n'; /* Problem:  trying to modify read only memory */
 getchar();
 return 0;
}

El siguiente programa funciona perfectamente bien ya que str[] se almacena en un segmento de pila grabable. 

C

int main()
{
 char str[] = "GfG";  /* Stored in stack segment like other auto variables */
 *(str+1) = 'n';   /* No problem: String is now GnG */
 getchar();
 return 0;
}

El programa a continuación también funciona perfectamente bien ya que los datos en str se almacenan en un segmento de almacenamiento dinámico grabable. 

C

int main()
{
  int size = 4;
  
  /* Stored in heap segment like other dynamically allocated things */
  char *str = (char *)malloc(sizeof(char)*size);
  *(str+0) = 'G'; 
  *(str+1) = 'f';  
  *(str+2) = 'G';    
  *(str+3) = '\0';  
  *(str+1) = 'n';  /* No problem: String is now GnG */
   getchar();
   return 0;
}     

Ejemplo 2 (Intente devolver una string desde una función) 
El siguiente programa funciona perfectamente bien ya que la string se almacena en un segmento compartido y los datos almacenados permanecen allí incluso después de la devolución de getString() 

C

char *getString()
{
  char *str = "GfG"; /* Stored in read only part of shared segment */
  
  /* No problem: remains at address str after getString() returns*/
  return str;  
}     
  
int main()
{
  printf("%s", getString());  
  getchar();
  return 0;
}

El siguiente programa también funciona perfectamente bien ya que la string se almacena en el segmento del montón y los datos almacenados en el segmento del montón persisten incluso después de la devolución de getString()  

C

char *getString()
{
  int size = 4;
  char *str = (char *)malloc(sizeof(char)*size); /*Stored in heap segment*/
  *(str+0) = 'G'; 
  *(str+1) = 'f';  
  *(str+2) = 'G';
  *(str+3) = '\0';  
    
  /* No problem: string remains at str after getString() returns */    
  return str;  
}     
int main()
{
  printf("%s", getString());  
  getchar();
  return 0;
}

Pero, el siguiente programa puede imprimir algunos datos basura ya que la string se almacena en el marco de la pila de la función getString() y es posible que los datos no estén allí después de que getString() regrese. 

C

char *getString()
{
  char str[] = "GfG"; /* Stored in stack segment */
  
  /* Problem: string may not be present after getString() returns */
  /* Problem can be solved if write static before char, i.e. static char str[] = "GfG";*/
  return str; 
}     
int main()
{
  printf("%s", getString());  
  getchar();
  return 0;
}

Escriba comentarios si encuentra algo incorrecto en el artículo anterior o si desea compartir más información sobre el almacenamiento de strings.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *