marcelogarberoglio / PI

Para realizar consultas
4 stars 0 forks source link

TP7 EJ8 #213

Open aggalan opened 1 year ago

aggalan commented 1 year ago

Hola Marcelo, tengo un problema con mi codigo, como que anda bien pero a veces me tira o un segmentation fault o stack smashing y aborta, tambien me aparece eso cuando uso el flag fsanitize, pero no se me ocurre donde puedo estar pisando memoria. Te dejo mi codigo.

include

include

include

include

include "../librerias/random.h"

include "../librerias/getnum.h"

define FILAS 5

define COLUMNAS 3

define BOLILLAS 90

define LINEA printf("----------------------------------------------------------------------------------- \n")

typedef int TipoLinea[FILAS]; typedef TipoLinea TipoCarton[COLUMNAS];

void generaCarton(TipoCarton jugador); int jugar(int bolillero[], TipoCarton jugador1, TipoCarton jugador2); int SacarBolilla(int bolillero[], int *cantBolillas); int controlarCarton(TipoCarton jugador, int bolilla); void imprimirCarton(TipoCarton jugador); int buscarBolilla(TipoCarton jugador, int bolilla); int controlarLineas(TipoLinea linea);

int main() { TipoCarton jugador1; TipoCarton jugador2;

randomize();

generaCarton(jugador1);
generaCarton(jugador2);

int bolillero[BOLILLAS];

for (int k = 0; k < BOLILLAS; k++)
{
    bolillero[k] = k + 1;
}

printf("\n \n \n");
printf("EL JUGADOR %d ES EL GANADOR", jugar(bolillero, jugador1, jugador2));
printf("\n \n \n");
return 0;

}

void generaCarton(TipoCarton jugador) {

int aux[BOLILLAS + 1];

for (int k = 0; k < BOLILLAS; k++)
{
    aux[k] = k + 1;
}

for (int i = 0; i < FILAS; i++)
{
    for (int j = 0; j < COLUMNAS; j++)
    {
        int n = BOLILLAS, pos;
        pos = randInt(0, BOLILLAS - 1);
        jugador[i][j] = aux[pos];
        aux[pos] = aux[n--];
    }
}

}

int jugar(int bolillero[], TipoCarton jugador1, TipoCarton jugador2) { int cantBolillas, bolilla, bingo1 = 0, bingo2 = 0, linea = 1, j1 = 0, j2 = 0; do {

    bolilla = SacarBolilla(bolillero, &cantBolillas);

    j1 = controlarCarton(jugador1, bolilla);
    j2 = controlarCarton(jugador2, bolilla);

    if (j1 == FILAS)
        bingo1 = 1;

    if (j2 == FILAS)
        bingo2 = 1;

    if (j1 > 0 && linea == 1)
    {
        printf("\n \n \n");
        printf("EL JUGADOR 1 GANO LA PRIMERA FILA \n");
        printf("\n \n \n");
        linea++;
    }
    else
    {
        if (j2 > 0 && linea == 1)
        {
            printf("\n \n \n");
            printf("EL JUGADOR 2 GANO LA PRIMERA FILA \n");
            printf("\n \n \n");
            linea++;
        }
    }
    LINEA;
    printf("CARTON JUGADOR 1 \n");
    imprimirCarton(jugador1);
    printf("\n \n \n");
    LINEA;
    printf("CARTON JUGADOR 2 \n");
    imprimirCarton(jugador2);

} while (!bingo1 && !bingo2);

if (bingo1)
    return 1;
else
    return 2;

}

int SacarBolilla(int bolillero[], int cantBolillas) { int n = cantBolillas, pos, bolilla;

pos = randInt(0, n - 1);
bolilla = bolillero[pos];
bolillero[pos] = bolillero[n--];

*cantBolillas = n;

return bolilla;

}

int buscarBolilla(TipoCarton jugador, int bolilla) { int flag = 0;

for (int i = 0; i < FILAS; i++)
{
    for (int j = 0; j < COLUMNAS; j++)
    {
        if (bolilla == jugador[i][j])
        {
            jugador[i][j] = 0;
            flag++;
            break;
        }
    }

    if (flag)
        break;
}

if (flag)

    return 1;
return 0;

}

void imprimirCarton(TipoCarton jugador) { for (int i = 0; i < FILAS; i++) { for (int j = 0; j < COLUMNAS; j++) { if (jugador[i][j] != 0) printf("%3d ", jugador[i][j]); }

    printf("\n");
}

}

int controlarLineas(TipoLinea linea) { int flag = 0;

for (int i = 0; i < COLUMNAS; i++)
{
    if (linea[i] != 0)
        flag++;
}

if (flag)
    return 0;
return 1;

}

int controlarCarton(TipoCarton jugador, int bolilla) { int filas = 0;

if (buscarBolilla(jugador, bolilla))
{
    for (int i = 0; i < FILAS; i++)
    {
        filas += controlarLineas(jugador[i]);
    }
}

return filas;

}

aggalan commented 1 year ago

tp7ej8..txt

marcelogarberoglio commented 1 year ago

Agregá el flag -g además del fsanitize, te va a mostrar cuál es la línea que está pisando memoria. Si con esa info seguís teniendo dudas, copiame el mensaje del fsanitize al abortar.

aggalan commented 1 year ago

aca esta el error

==3264==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd6b732bac at pc 0x55c3e6b998d6 bp 0x7ffd6b7328c0 sp 0x7ffd6b7328b0 WRITE of size 4 at 0x7ffd6b732bac thread T0

0 0x55c3e6b998d5 in generaCarton /mnt/c/Users/Agustin/OneDrive/Documentos/ITBA/PI/tp7/tp7ej8.c:62

#1 0x55c3e6b994de in main /mnt/c/Users/Agustin/OneDrive/Documentos/ITBA/PI/tp7/tp7ej8.c:30
#2 0x7fe2eed11d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#3 0x7fe2eed11e3f in __libc_start_main_impl ../csu/libc-start.c:392
#4 0x55c3e6b99324 in _start (/mnt/c/Users/Agustin/OneDrive/Documentos/ITBA/PI/tp7/a.out+0x2324)

Address 0x7ffd6b732bac is located in stack of thread T0 at offset 108 in frame

0 0x55c3e6b993f8 in main /mnt/c/Users/Agustin/OneDrive/Documentos/ITBA/PI/tp7/tp7ej8.c:24

This frame has 3 object(s): [48, 108) 'jugador1' (line 25) <== Memory access at offset 108 overflows this variable [144, 204) 'jugador2' (line 26) [240, 600) 'bolillero' (line 33) HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions are supported) SUMMARY: AddressSanitizer: stack-buffer-overflow /mnt/c/Users/Agustin/OneDrive/Documentos/ITBA/PI/tp7/tp7ej8.c:62 in generaCarton Shadow bytes around the buggy address: 0x10002d6de520: f1 f1 f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 0x10002d6de530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10002d6de540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10002d6de550: 00 00 00 04 f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00 0x10002d6de560: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f1 f1 00 00 =>0x10002d6de570: 00 00 00 00 00[04]f2 f2 f2 f2 00 00 00 00 00 00 0x10002d6de580: 00 04 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 0x10002d6de590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10002d6de5a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10002d6de5b0: 00 00 00 f3 f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00 0x10002d6de5c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==3264==ABORTING

marcelogarberoglio commented 1 year ago

Según el txt que mandaste la línea 62 es esta

jugador[i][j] = aux[pos];

Está mal definido el tipoCarton, no tiene que ser

define FILAS 5

define COLUMNAS 3

typedef int TipoLinea[FILAS]; typedef TipoLinea TipoCarton[COLUMNAS];

sino

define FILAS 3

define COLUMNAS 5

typedef int TipoLinea[COLUMNAS]; typedef TipoLinea TipoCarton[FILAS];

ya que una línea tiene 5 valores. Y un cartón tiene 3 líneas. Vos lo estás definido como de 3x5, pero luego accdés como si fuera de 5x3

Además fijate que essto no está bien pos = randInt(0, BOLILLAS - 1); el segundo argumento de randint deberían ser la cantidad de bolillas que aún no salieron

aggalan commented 1 year ago

buenisimo ahi cambie eso. La parte de eso que queres que me fije me parece la sacaste de generarCarton que solo se ejecuta una vez por jugador y teniendo en cuenta todas las bolillas.

Lo que puse en la parte de SacarBolilla( teniendo en cuenta las que quedan)

int SacarBolilla(int bolillero[], int *cantBolillas) { int pos, bolilla;

pos = randInt(0, *cantBolillas - 1) ;
bolilla = bolillero[pos];
bolillero[pos] = bolillero[*cantBolillas];
(*cantBolillas)--;

return bolilla;

}

Lo que pasa que ahora me tira que el problema esta aca.