2011-02-17 16 views
5

Estoy tratando de implementar un cifrado de desplazamiento básico en C++. No puedo avanzar hasta que descubra qué está causando la falla de segmentación. Pasé por el código usando gdb y el problema parece provenir del iterador.¿Por qué aparece una falla de segmentación al iterar a través de esta cadena?

1 #include <iostream> 
2 #include <string> 
3 
4 std::string encrypt (std::string plain, int key); 
5 
6 int main() 
7 { 
8   std::string plaintext; 
9   std::getline(std::cin,plaintext,'\n'); 
10  encrypt(plaintext,3); 
11 } 
12 
13 std::string encrypt(std::string plain, int key) 
14 { 
15   std::string::iterator ic; 
16   for (ic= plain.begin(); ic != plain.end();++ic) 
17   { 
18     std::cout <<*ic + key << std::endl; 
19   } 
20 } 

error:

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7b73ef1 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()() from /usr/lib/libstdc++.so.6 

Respuesta

8

Usted ha declarado encrypt como devolver un std::string, pero no devuelve nada de la función. Debe devolver un valor o debe cambiar el tipo de devolución para que sea void para indicar que la función no devuelve nada.

En cuanto a por qué está fallando como está escrito, solo puedo especular. Es probable que el compilador haya generado una llamada al destructor std::string en main para limpiar el objeto std::string que devuelve encrypt. Como encrypt en realidad no devuelve nada, el destructor termina siendo llamado por un objeto que no existe. La memoria que debería contener el objeto probablemente solo contenga datos basura y al destructor no le gusta eso.

+0

pero ¿por qué obtiene un SIG en '~ basic_string'? – osgx

+0

ah gracias que lo arregló –

+0

Ni siquiera sabía que esto podría compilar. Por cierto, @kernel, ¡no olvides aceptar la respuesta correcta! – Marlon

1

El problema es que su función encrypt carece de una declaración return.

Añadir

return "blah blah"; 

Además de solucionar esto, considere la posibilidad de transmisión de cadenas por referencia a const, como

std::string const& plain 

Saludos & HTH.,

+0

y luego usaría const_iterator? o eso no importaría? –

+1

@the_kernel: deberías/deberías usar un 'const_iterator', sí. –

+0

bien muchas gracias. todas estas sugerencias han sido muy informativas/útiles. –

3

Grabación de un bucle, pero cambiándolo desde usar un índice hasta usar un iterador suele ser un error. Si vas a utilizar un ciclo explícito, por lo general tiene más sentido seguir usando un índice, al menos para algo como string que permite el acceso aleatorio. El punto principal de los iteradores es habilitar algoritmos genéricos que no estén acoplados a contenedores. Para hacer un buen uso de un repetidor, lo utiliza con un algoritmo:

int main() { 
    std::string plaintext; 
    std::getline(std::cin, plaintext); 

    std::transform(plaintext.begin(), plaintext.end(), 
        std::ostream_iterator<char>(std::cout), 
        std::bind2nd(std::plus<int>(), 3)); 
    return 0; 
} 

Editar: Desde Hans Passant lo mencionó, una versión usando una expresión lambda se vería así:

std::transform(line.begin(), line.end(), 
       std::ostream_iterator<char>(std::cout), 
       [](char ch) { return ch+'\03'; }); 

Sólo relativamente compiladores recientes apoyan esto, sin embargo - gcc> = 4.6, Visual Studio> = 2010.

+0

Eso definitivamente parece más intuitivo que lo que estaba tratando de hacer. gracias, miraré más en los algoritmos STL –

+0

Use lambdas para realizar esa venta. –

5

[C++2003 Standard section 6.6.3-2] Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

este es un error muy fácil de hacer si su compilador no emite ningún aviso. Puede ahorrarse mucha depuración habilitando tantas advertencias de compilador como sea posible. En el caso de gcc/g ++, sugiero compilar con "-Wall -Werror" para cualquier código nuevo que esté escribiendo. Con esas opciones, la compilación de este programa falla con el siguiente mensaje:

cc1plus: warnings being treated as errors 
In function 'std::string encrypt(std::string, int)': 
Line 20: warning: control reaches end of non-void function 
+0

que definitivamente haría la vida mucho más fácil gracias a la sugerencia –

Cuestiones relacionadas