C++ puntero no válido error

Estoy consiguiendo no válido error en el código de abajo no veo por qué no. Todo lo que estoy tratando de hacer es eliminar libre de algunas de las cadenas en las que el montón de un vector:

void func() {
    vector<string>* vec = new vector<string>;
    vec->push_back(*(new string("1")));
    vec->push_back(*(new string("2")));

    for(vector<string>::iterator itr = vec->begin(); itr != vec->end(); ++itr)
    {
        string* ptr = &(*itr);
        delete(ptr);
    }
}

EDITAR: es porque push_back crea una copia de la cadena?

  • vec->push_back(*(new string("1"))); = pérdida de memoria
  • porque push_back() crea una copia y sale de la cadena en el montón de referencia, ¿correcto?
  • Si usted realmente desea asignar en el montón, más seguro de usar boost.org/doc/libs/1_35_0/libs/ptr_container/doc/…
  • correcto
InformationsquelleAutor user1861088 | 2013-02-22

3 Kommentare

  1. 6

    Su error es debido a que el elemento no se asigna de forma dinámica; la vector es. Lo que estamos tratando de hacer requeriría:

    void func() 
    {
        vector<string*> vec;
        vec.push_back(new string("1"));
        vec.push_back(new string("2"));
    
        for(vector<string*>::iterator itr = vec.begin(); itr != vec.end(); ++itr)
        {
            string* ptr = *itr;
            delete(ptr);
        }
    }

    Pero sinceramente veo poca razón para ello. Como-escrito el código no sólo los intentos de borrar la memoria que en realidad nunca asignados, se filtra lo que las asignaciones se hizo hacer.

    No son razones para almacenar punteros a objetos en un vector como este (como los objetos que son realmente de otro contenedor en otro lugar y necesita un temporal lista de ellos para un tipo de operación sin alterar el contenido original), pero algo me dice que eres una de las maneras de tener esa necesidad.

    • Yo entiendo. La situación es que no puedo usar un vector de punteros. Bueno, yo estaba confundido acerca de algunos conceptos. Pero creo que lo entiendo ahora.
    • Que puede el uso de un vector de punteros. Pero usted probablemente no tiene razón.
    • Charles es correcta. no son razones para el uso de un vector de punteros (cito uno en mi respuesta), pero yo no creo que esos usos son aplicables a sus necesidades actuales.
    • ¿por qué no? lo siento soy nuevo en C++. Si yo en lugar de devolución de copias en todas partes en lugar de punteros, ¿no sería una mala práctica, porque una gran cantidad de tiempo se dedica a la creación de copias? ¿Por qué el uso de punteros no es el preferido en C++ en esta situación?
    • usted no necesita devolver las copias impresas. C++ tiene referencias.
    • En primer lugar, con respecto a los punteros de ser dueño de los recursos, vea este sencillo doc que lo resume muy bien. Si usted debe usar punteros, y los punteros propia los recursos que están a punto de darles cerebros (hacerlos punteros inteligentes). De lo contrario, la banda de rodadura muy, muy cuidadosamente. el ejemplo de La razón por la que me citan para el uso de un vector de desnudos de punteros es considerable debido a los punteros en el vector no sería dueño de los recursos que están a punto de a. Difícil de imaginar, lo sé, pero importante.
    • La Salvia pero si puedo crear un objeto en la pila local de una función que devuelve una referencia a ella, una vez que la función devuelve el objeto se ha ido ?
    • que es un problema diferente se accede a un elemento que se almacena en un contenedor. En general, usted realmente necesita entender C++ propiedad semántica si se va a utilizar punteros. Si usted necesita devolver un objeto a partir de una función de retorno por valor. C++11 ha de mover la semántica que generalmente se asegurará de que el objeto se mueve, en lugar de copiar. De lo contrario, si no estás usando C++11, considerando la posibilidad de retornar un puntero inteligente o (menos de preferencia) el uso de un «valor de salida parámetro».
    • lo consiguió. gracias por los comentarios chicos! Estoy empezando a aceptar el hecho de que C++ es mucho más complicado (y más inteligente para el caso) que C + STL, lol.
    • Absolutamente. se ha llegado a un tiempo desde el original C++ w/STL hace muchas lunas. El 1300+ páginas de el C++11 documento de las normas es en sí mismo un testimonio de cuán mejor es definido.

  2. 4

    En primer lugar, la línea de

    vec->push_back(*(new string("1")));

    está causando una pérdida de memoria. El valor devuelto desde new string("1") es un puntero a un recién asignado objeto string. Pero al eliminar la referencia y la inserta en el vector, un copia de la asigna el montón de objeto se crea y se inserta. Sin embargo, el verdadero objeto string que originalmente asignados en el montón se filtró.

    Esencialmente, su vector es el almacenamiento de la cadena de objetos de valor, no los punteros a objetos string. La copia del objeto string que se inserta en el vector NO es un montón asignado objeto (no un objeto asignado con new). Y, por supuesto, usted no puede delete algo que no estaba asignado con new. Así que cuando usted llama delete(ptr) que están causando un comportamiento indefinido.

    Lo que parece que queremos aquí es un:

    vector<string*>* vec = new vector<string*>;

    Sin embargo, en general no veo ninguna razón por qué usted está asignando todo el montón. En C++ es preferible utilizar la asignación de pila y contenedores con valor semántica, siempre que sea factible, a menos que haya alguna razón por qué usted necesita montón de asignación (por ejemplo, un contenedor de objetos polimórficos, en cuyo caso se debe utilizar punteros inteligentes de todos modos). Generalmente, cuando los nuevos programadores de C++ uso asigna el montón de objetos y la new palabra clave en todo el lugar, es una señal de que están mal transliterating un estilo de programación importados de un lenguaje administrado como Java o C#.

  3. 3

    No, no lo eres – su vector de tiendas string de los objetos, no los punteros a string objetos. Es por eso que usted tiene el * en su push_back llamada – se desreferenciar el puntero devuelto.

    Usted está agregando un copia de la dinámica de la cadena de crear con new y que la dinámica de la cadena se pierde, ya que nunca almacenar el puntero que new devuelve.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea