2011-02-04 13 views
6

He estado tratando de buscar una razón por la cual el siguiente código está fallando, y no pude encontrar uno. Entonces, disculpen mi ignorancia y háganme saber lo que está pasando aquí.Char * p, y scanf

#include<stdio.h> 
int main(void){ 
char* p="Hi, this is not going to work"; 
scanf("%s",p); 
return 0; 
} 

Por lo que he entendido, he creado un puntero p a un área contigua en la memoria del tamaño 29 + 1 (para la \ 0). ¿Por qué no puedo usar scanf para cambiar el contenido de eso?

P.S Corrígeme si dije algo mal sobre char *.

Respuesta

14
char* p="Hi, this is not going to work"; 

esto no asigna memoria para que usted escriba

esto crea un String Literal que se traduce en Undefined Behaviour cada vez que intenta cambiar su contenido.

utilizar p como un amortiguador para su scanf hacer algo como char * p = malloc(sizeof(char) * 128); // 128 is an Example

O

que así podría hacer:

char p[]="Hi, this is not going to work"; 

que supongo que es lo que realmente quería hacer .

Tenga en cuenta que esto todavía puede terminar siendo UB porque scanf() no comprueba si el lugar que está utilizando es efectivamente memoria de escritura válida.

recordar:

char * p es una cadena literal y no debe modificarse

char p[] = "..." asigna suficiente memoria para contener la cadena dentro de la "..." y pueden ser modificados (su contenido me refiero).

Editar:

Un buen truco para evitar UB es

char * p = malloc(sizeof(char) * 128); 
scanf("%126s",s); 
+0

Si ese es el caso, ¿cómo leo una cadena de longitud desconocida? – Fingolfin

+0

@Adel, hizo una pequeña Edición, mira la última línea – Muggen

+0

¡Qué bueno, gracias! Pero, ¿qué hacer si no puedo predecir la longitud de la cadena que se va a escanear? – Fingolfin

-3

scanf() analiza los datos ingresados ​​desde stdin (normalmente, el teclado). Creo que quieres sscanf().

Sin embargo, el propósito de scanf() es separar una secuencia con secuencias de escape predefinidas, que su cadena de prueba no tiene. Eso hace que no quede claro exactamente lo que estás tratando de hacer.

Tenga en cuenta que sscanf() toma un argumento adicional como primer argumento, que especifica la cadena que se analiza.

+0

Creo que la pregunta es por qué scanf no funciona. Respuesta de Muggen explica que – user210504

+0

Veo varias cosas mal con el código del OP, por lo que es un poco difícil saber exactamente lo que estaba tratando de lograr. –

6

p apunta a un literal constante, que de hecho puede residir en un área de memoria de solo lectura (depende de la implementación). En cualquier caso, intentar sobrescribirlo es comportamiento indefinido. Es decir. puede resultar en nada, o un bloqueo inmediato, o una corrupción de memoria oculta que causa problemas misteriosos mucho más tarde. Nunca haga eso.

+1

@Downvoter, ¿te importa explicarlo? –

+0

@Peter, no perdoné, pero no veo una razón de por qué -1, así que +1 – Muggen

+0

Acabo de eliminar mi voto negativo. Vi alguna otra explicación antes. Supongo que editaste esto. – user210504

0

Se está fallando porque la memoria no se ha asignado para p. Asigne memoria para p y debería estar bien. Lo que tienes es un área de memoria constante que apunta hacia p. Cuando intente escribir algo en este segmento de datos, el entorno de tiempo de ejecución provocará una trampa que provocará un bloqueo.

Espero que esto responda a su pregunta