2009-06-03 24 views
5

En el código siguiente, la línea:Fallo de segmentación - Char puntero

*end = *front; 

da un fallo de segmentación. Hice una pregunta similar here pero no estoy seguro de si esto es porque tengo dos copias de num. Por favor explica por qué es seg-faulting. Gracias.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

char* getPalin(char* num); 

int main() 
{ 
    char* num = (char*)malloc(100); 

    num = "123456"; 

    printf("%s\n", getPalin(num)); 

    return 0; 
} 

char* getPalin(char* num) 
{ 
    int length = strlen(num); 

    if (length % 2 == 0) 
    { 
     char* front = num; 
     char* end = num + strlen(num) - 1; //pointer to end 

     while(front != num + (length/2)) //pointers not middle yet 
     { 
      *end = *front; 

      printf("%c", *end); 

      front++; 
      end--; 
     } 
    } 

    return num; 
} 

Respuesta

15

Estas dos líneas:

char* num = (char*)malloc(100); 
num = "123456"; 

tienen el siguiente efecto.

La primera asigna 100 bytes y establece num para que apunte a esos bytes.

El segundo cambia num para apuntar a la cadena "123456" que es casi seguro en la memoria de solo lectura.

Cualquier intento de cambiar el contenido de la memoria de solo lectura provocará una violación de la segmentación. Debe copiar la cadena en el malloc 'd num antes de intentar cambiarlo, con:

strcpy (num, "123456"); 

Esa es la línea que debe tener en el que tiene actualmente:

num = "123456"; 
4

Use

strncpy(num, "123456", 100); 

en lugar de

num = "123456"; 
+0

lo siento, no sizeof (num), pero el tamaño de la memoria asignada, es decir 100. Es decir. strncpy (num, "123456", 100); – Konstantin

+3

OP pidió explicaciones pero usted solo dio una solución. Y nunca olvides agregar manualmente terminador nulo después de strncpy porque no está garantizado que strncpy lo agregue. Sé que no es relevante en este ejemplo porque "123456" es más corto que 100 bytes, pero si decidiste usar strncpy en lugar de strcpy, úsalo correctamente. Evitaste un problema potencial (desbordamiento del búfer) pero introdujiste otro (cadena sin terminar) . – qrdl

+0

@qrdl: siempre que el tamaño de destino especificado en strncpy sea mayor que la longitud de la cadena, strncpy se rellenará automáticamente con caracteres nulos. Solo si el tamaño de destino se especifica como inferior a la longitud de cadena que se va a copiar, es posible que se omita el terminador nulo. Otro punto importante es recordar que strncpy NO verificará que haya suficiente espacio en la memoria de destino. Entonces supongo que strncpy (num, "123456", sizeof (num)) sería más correcto. – ChrisBD

1

De acuerdo con la respuesta de Konstantin.

Ya ha asignado memoria para num con la instrucción malloc.

Si hubieras no, entonces usted podría salirse con:

char* num = "123456"; 

que definiría y asignar memoria sobre la marcha, pero lo más probable es ser asignado como una constante y por lo tanto sólo lectura.

Usar strncpy en lugar de strcpy para copiar "123456" asegurará que cualquier espacio adicional más allá del final del string null terminator también se inicialice como nulo, siempre que especifique n como 100 (para su ejemplo). De lo contrario, sin inicializar la memoria asignada por malloc a null (memset (num, 0, 100)), es concebible que pueda avanzar más allá del final de la cadena.

Casi lo olvido. Es recomendable usar strcpy_s o strncpy_s ya que son más seguros, aunque para tu código no importará.

+0

Realmente considero esas dos funciones _s() como una muleta para las personas que no saben cómo codificar a la defensiva [es decir, comprueben las condiciones previas primero - Nunca he encontrado la necesidad de usar strncpy() y aún mi código es tan "seguro" como cualquiera que use las variantes _s()]. Además de eso, todavía no son parte del estándar. – paxdiablo

+0

De ahí la razón por la que dije aconsejable. Nunca deja de sorprenderme cuánto software comercial se deja abierto a los ataques de desbordamiento del buffer. – ChrisBD

0

El motivo del error es:

char* num = (char*)malloc(100); 

En esta línea se ha declarado num como un puntero a una matriz o puntero a su primer elemento no como una cadena.

num = "123456"; 

Esta línea ha utilizado num como lo ha declarado como una cadena.Esto es una violación de la segmentación y, por lo tanto, de la falla seg. El preferible (correcto) sintaxis de su código es:

char num[100]; 
    strcpy(num,"123456"); //Even if you use num="123456"; here it would still be wrong 

O

char* num = (char*)malloc(100); 
    strcpy(num,"123456"); 

O

char num[100]={'1','2','3','4','5','6'}; 

Cualquiera de ellos podría hacer su trabajo.

Cuestiones relacionadas