User Tag List

Resultados 1 al 6 de 6

Tema: ¡¡Ayuda a un novato!! Violación de segmento ('core' generado)

  1. #1

    Fecha de ingreso
    Jan 2010
    Ubicación
    En el seco valle del Vinalopó
    Mensajes
    801
    Mencionado
    2 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    80
    Agradecer Thanks Received 
    113
    Thanked in
    Agradecido 82 veces en [ARG:2 UNDEFINED] posts

    ¡¡Ayuda a un novato!! Violación de segmento ('core' generado)

    Hola buenas! Es la primera vez que pregunto algo como "programador" en este foro xD. Soy un completo principiante y llevo pocos meses programando. Mi pregunta es sobre el siguiente módulo de mi programa:
    bool addFighter(Ship &ship)
    {

    char op[3];
    int num, cod, i, j, pos;
    bool salida;
    salida=false;
    cout<<"Enter fighter type (tf/tb/ti/ta):";
    cin.getline(op,3);
    cod=5;


    for(i=0; i<MAXFIGHTERS/2; i++){
    if(op==FIGHTERABR[i])
    cod=i;
    }

    if(cod>=MAXFIGHTERS/2)
    error(WRONG_FIGHTER_TYPE);
    else{
    cout<<"Number of fighters:";
    cin>>num;
    if(num*FIGHTERTABLE[cod].cost > ship.credits)
    error(NO_FUNDS);
    else if(ship.fighters.size()+num>IMPSHIPCAPACITY)
    error(CAPACITY_EXCEEDED);
    else{
    for(j=0; j<num; j++){
    pos=ship.fighters.size() + j;
    ship.fighters[pos] = FIGHTERTABLE[cod];
    ship.credits = ship.credits-FIGHTERTABLE[cod].cost;
    salida=true;

    }

    }


    }
    return salida;
    }
    Lo que debe hacer este módulo es agregar en la última posición del vector ship.fighters un nuevo caza de combate si se cumple que hay suficiente espacio (definido por IMPSHIPCAPACITY) y se tienen suficientes fondos para pagarlo(ship.credits). Tras compilar y ejecutar los tres casos de error funcionan perfectamente (wrong fighter type, capacity exceeded y no funds) pero si introduzco datos validos me salta lo de "Violación de segmento ('core' generado)". Puede alguno de vosotros ver el por que?
    Adjunto el código completo también:
    Spoiler: Ver
    #include <iostream>
    #include <vector>
    #include <cstdlib>

    using namespace std;

    typedef struct {
    string type; // TIE Fighter, X-Wing, ...
    int velocity;
    int attack; // attack power
    int shield; // current shield status. if <=0, the fighter is considered destroyed
    int cost; // cost in credits
    } Fighter;


    typedef struct {
    bool side; // IMPERIAL or REBEL
    int maxCapacity; // maximum capacity of fighters allowed in the ship
    int credits; // credits remaining to buy fighters, make repairs or improvements
    int wins; // enemy fighters destroyed
    int losses; // fighters lost
    vector<Fighter> fighters; // fighters inside the ship
    } Ship;


    // Fighters table

    const int MAXFIGHTERS=8;

    // abbreviations (to use in option "Add fighter")
    const string FIGHTERABR[]= { "tf", "tb", "ti", "ta",
    "xw", "yw", "aw", "bw"
    };

    const Fighter FIGHTERTABLE[] = { //Tabla de los posibles cazas que se pueden utilizar
    { "TIE-Fighter", 150, 75, 30, 45 },
    { "TIE-Bomber", 80, 150, 45, 75 },
    { "TIE-Interceptor", 180, 65, 30, 55 },
    { "TIE-Advanced", 160, 80, 90, 95 },
    { "X-Wing", 175, 90, 75, 65 },
    { "Y-Wing", 90, 150, 90, 90 },
    { "A-Wing", 200, 60, 50, 45 },
    { "B-Wing", 120, 200, 90, 100 }
    };


    // ship constants
    const bool IMPERIAL=false;
    const bool REBEL=true;

    const int IMPSHIPCAPACITY=30;
    const int REBSHIPCAPACITY=35;

    const int initialImperialShipDotation[] = {10,5,5,5,0,0,0,0};
    // 10 TIE-Fighters, 5 TIE-Bombers, 5 TIE-Interceptors, 5 TIE-Advanced, 0 X-Wing, ....

    const int initialRebelShipDotation[] = {0,0,0,0,10,5,8,5};
    // 0 TIE-Fighters ..., 10 X-Wing, 5 Y-Wing, 8 A-Wing, 5 B-Wing

    // ship initial credits
    const int CREDITS_INITIAL=2000;

    // error numbers
    const int UNKNOWN_OPTION=1;
    const int WRONG_FIGHTER_TYPE=2;
    const int CAPACITY_EXCEEDED=3;
    const int WRONG_NUMBER=4;
    const int NO_FUNDS=5;
    const int NO_FIGHTERS=6;

    //---------------------------------------------------
    void error(int n)
    {
    cout << "ERROR (" << n << "): " ;

    switch (n)
    {
    case UNKNOWN_OPTION:
    cout << "unknown option" << endl;
    break;
    case WRONG_FIGHTER_TYPE:
    cout << "wrong fighter type" << endl;
    break;
    case CAPACITY_EXCEEDED:
    cout << "ship capactity exceeded" << endl;
    break;
    case WRONG_NUMBER:
    cout << "wrong number" << endl;
    break;
    case NO_FUNDS:
    cout << "not enough credits" << endl;
    break;
    case NO_FIGHTERS:
    cout << "not enough fighters" << endl;
    break;
    }
    }

    //---------------------------------------------------
    int getRandomNumber(int max)
    {
    // Genera un número aleatorio entre 0 y maximo-1
    //
    int na;

    na = (int)(((double)max)*rand()/(RAND_MAX+1.0));
    return na;
    }


    //---------------------------------------------------
    void initializeShip(Ship &ship,bool side)
    {
    int i, j;


    if(side==REBEL){
    ship.side=REBEL;
    ship.maxCapacity=REBSHIPCAPACITY;
    ship.credits=CREDITS_INITIAL;
    ship.wins=0;
    ship.losses=0;
    for(i=0; i<MAXFIGHTERS; i++){
    if(initialRebelShipDotation[i]!=0)
    for(j=0; j<initialRebelShipDotation[i]; j++){
    ship.fighters.push_back(FIGHTERTABLE[i]);

    }
    }
    }else{
    ship.side=IMPERIAL;
    ship.maxCapacity=IMPSHIPCAPACITY;
    ship.credits=CREDITS_INITIAL;
    ship.wins=0;
    ship.losses=0;
    for(i=0; i<MAXFIGHTERS; i++){
    if(initialImperialShipDotation[i]!=0)
    for(j=0; j<initialImperialShipDotation[i]; j++){
    ship.fighters.push_back(FIGHTERTABLE[i]);

    }

    }
    }
    }


    //---------------------------------------------------
    void listFighter(const Fighter &f)//Saca a pantalla las características de un único caza
    {
    cout<<f.type<<"(v="<<f.velocity<<", a="<<f.attack<<", s="<<f.shield<<", c="<<f.cost<<")"<<endl;

    }

    void listFighters(const vector<Fighter> &vf) //Este módulo convierte los resultados individuales que desarolla el módulo anterior en una lista numerada
    {
    int unsigned i;
    for(i=0; i<vf.size(); i++){ //Recordar que vector.size() da el TAMAÑO del vector; no la POSICIÓN final (Esta nota es para mí, supongo que el que lea esto ya lo sabrá)
    cout<<"["<<i+1<<"] ";
    listFighter(vf[i]);
    }
    }

    void listShip(const Ship &ship)
    {
    cout<<"Ship info: max. capacity="<<ship.maxCapacity<<", side="<<ship.side<<", credits="<<ship.credits<<", wins="<<ship.wins<<", losses="<<ship.losses<<endl;
    listFighters(ship.fighters);
    }
    bool addFighter(Ship &ship)
    {

    char op[3];
    int num, cod, i, j, pos;
    bool salida;
    salida=false;
    cout<<"Enter fighter type (tf/tb/ti/ta):";
    cin.getline(op,3);
    cod=5;


    for(i=0; i<MAXFIGHTERS/2; i++){
    if(op==FIGHTERABR[i])
    cod=i;
    }

    if(cod>=MAXFIGHTERS/2)
    error(WRONG_FIGHTER_TYPE);
    else{
    cout<<"Number of fighters:";
    cin>>num;
    if(num*FIGHTERTABLE[cod].cost > ship.credits)
    error(NO_FUNDS);
    else if(ship.fighters.size()+num>IMPSHIPCAPACITY)
    error(CAPACITY_EXCEEDED);
    else{
    for(j=0; j<num; j++){
    pos=ship.fighters.size() + j;
    ship.fighters[pos] = FIGHTERTABLE[cod];
    ship.credits = ship.credits-FIGHTERTABLE[cod].cost;
    salida=true;

    }

    }


    }
    return salida;
    }
    int main(int argc,char *argv[])
    {
    Ship imperialDestroyer, rebelShip;

    bool side;

    srand(1); // inicializar secuencia de números aleatorios: NO TOCAR
    side=REBEL;
    initializeShip(rebelShip, side);
    side=IMPERIAL;
    initializeShip(imperialDestroyer, side);


    listShip(imperialDestroyer);
    listShip(rebelShip);
    side=addFighter(imperialDestroyer);
    }



    Edit: Ufff... perdonad que no haya nigún tipo de sangrado, ha desaparecido en el copia y pega

  2. #2

    Fecha de ingreso
    Jan 2007
    Ubicación
    Ciudad Catedral, Reino de Dick
    Mensajes
    3,638
    Mencionado
    7 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    151
    Agradecer Thanks Received 
    100
    Thanked in
    Agradecido 79 veces en [ARG:2 UNDEFINED] posts
    Puede haber chorrocientasmil razones y media.

    Te recomiendo que lo ejecutes con un depurador (GDB, por ejemplo), a ver dónde falla exactamente y tirar desde allí.
    Proyectos actuales ----> MinGRo
    Entorno de desarrollo ----> FreePascal | Vim

  3. #3

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,342
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    368
    Agradecer Thanks Received 
    1,793
    Thanked in
    Agradecido 945 veces en [ARG:2 UNDEFINED] posts
    En una ullada rápida, estas línes de código no me gustan nada:

    Código:
    for(j=0; j<num; j++){
        pos=ship.fighters.size() + j;
        ship.fighters[pos] = FIGHTERTABLE[cod];
        ....
    }
    Con esas líneas accedes sí o sí fuera del vector de fighters, ¿no? Porque pos va a ser siempre mayor que fighters.length()
    "Todo es absolutamente falso, salvo alguna cosa"

  4. El siguiente usuario agradece a juanvvc este mensaje:

    Daniel A. (25/02/2016)

  5. #4

    Fecha de ingreso
    Jan 2010
    Ubicación
    En el seco valle del Vinalopó
    Mensajes
    801
    Mencionado
    2 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    80
    Agradecer Thanks Received 
    113
    Thanked in
    Agradecido 82 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por juanvvc Ver mensaje
    En una ullada rápida, estas línes de código no me gustan nada:

    Código:
    for(j=0; j<num; j++){
        pos=ship.fighters.size() + j;
        ship.fighters[pos] = FIGHTERTABLE[cod];
        ....
    }
    Con esas líneas accedes sí o sí fuera del vector de fighters, ¿no? Porque pos va a ser siempre mayor que fighters.length()
    Solucionado. Muchisimas gracias.
    for(j=0; j<num; j++){

    ship.fighters.push_back(FIGHTERTABLE[cod]);
    ship.credits = ship.credits-FIGHTERTABLE[cod].cost;
    salida=true;

    }
    Que encima ya tenia la solución delante de las narices porque había utilizado la función push_back en el módulo initialiceShip, manda huevos

  6. #5

    Fecha de ingreso
    Jun 2003
    Ubicación
    Barcelona
    Mensajes
    423
    Mencionado
    0 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    4
    Agradecer Thanks Received 
    2
    Thanked in
    Agradecido %1$s veces en 1 post
    Para la próxima, te recomiendo que en estos casos uses valgrind o sucedáneos.
    Un saludo!

  7. #6

    Fecha de ingreso
    Sep 2006
    Ubicación
    Malaga
    Mensajes
    7,561
    Mencionado
    47 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    1,668
    Agradecer Thanks Received 
    1,922
    Thanked in
    Agradecido 1,289 veces en [ARG:2 UNDEFINED] posts
    ¿Por que hay constantes que tienen un guion entre cada palabra y otras no? Intenta ser mas uniforme con estas cosas.
    No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.


    It is an undisputed truth that the Atari ST gets the best out of coders. No dedicated hardware, just the CPU and a frame buffer! Some call it Spartan, others name it Power Without The Price, and a select few say `challenge accepted'! --- by spkr from smfx

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •