# Laboratorio de la semana 5: imágenes de cualquier tamaño y cacería de errores

Los comandos se corren desde `code/week-05`. Las ideas están en los apuntes, en la sección
"El laboratorio, paso a paso".

| Archivo | Qué es | ¿Lo cambian? |
|---|---|---|
| `image.h` | Lo que ofrece el módulo de imágenes, ahora sin tamaño máximo | No |
| `image.c` | El módulo: `read_number`, guardar, comparar y dibujar ya están hechos | **Sí** |
| `filters.h`, `filters.c` | Los filtros de la semana 4, ya adaptados | No |
| `image_tests.c` | Sus pruebas del módulo | **Sí** |
| `image_demo.c` | Carga `images/range.pgm`, de 96 x 28, y la dibuja | No |
| `str_tools.h` | Lo que deben hacer `str_duplicate` y `str_concat` | No |
| `str_tools.c`, `str_tests.c` | Las dos funciones y sus pruebas | **Sí** |
| `hunt/*.c` | Los cinco programas de la cacería | **Sí** |
| `hunt/report.md` | Su explicación de cada error | **Sí** |
| `int_array.h` | Lo que debe hacer el arreglo que crece | No |
| `int_array.c`, `array_tests.c` | El arreglo y sus pruebas | **Sí** |
| `sum_file.c` | Usa el arreglo para resumir un archivo de enteros | No |

```sh
make lab        # compila sus programas y sus pruebas en build/lab/
make hunt       # compila la cacería en build/hunt/, con sanitizers y para valgrind
make test-lab   # comprueba todo; falla hasta que terminen
```

Cada sesión está pensada para unos 90 minutos de trabajo, y el resto queda para preguntar.

## Sesión 1

### Parte 1: leer antes de cambiar (10 minutos)

Lean `image.h` completo y luego `image_from_values`, `read_number` e `image_show` en
`image.c`. Respondan por escrito, sin ejecutar nada.

1. Según `image.h`, ¿quién es owner de lo que devuelve `image_load`? ¿Cómo debe liberarlo?
2. En una imagen de 3 x 2, ¿cuántos bloques hay en el heap? ¿Cuántos bytes pide cada uno,
   según `sizeof`?
3. En `image_from_values`, ¿qué pasaría con la memoria si, al encontrar un valor malo, se
   hiciera solo `return NULL`?
4. ¿Por qué `valid_size` compara `width <= INT_MAX / height`, en lugar de calcular
   `width * height` y comparar el resultado?

### Parte 2: el módulo sin límite (50 minutos)

En `image.c`, escriban `image_allocate`, `image_new` e `image_free`, y terminen `read_image`.
Agreguen sus casos en `image_tests.c`, que trae uno de modelo.

```sh
make lab && build/lab/image_tests
build/lab/image_demo
```

`read_image` no debe llamar a `image_new`: esa función escribe todos los píxeles antes de
leer el primero. Si el archivo dice que la imagen es enorme y trae pocos datos, ese trabajo
se desperdicia.

### Parte 3: cadenas que devuelven memoria nueva (30 minutos)

En `str_tools.c`, escriban `str_duplicate` y `str_concat`, según `str_tools.h`, con sus
pruebas en `str_tests.c`. No usen `strdup`: no es parte de C17. Prueben la cadena vacía.

```sh
make lab && build/lab/str_tests
```

Si no alcanza el tiempo, `str_concat` y sus pruebas quedan para antes de la sesión 2.

## Sesión 2

### Parte 4: la cacería (50 minutos, unos 10 por programa)

Cada programa de `hunt/` tiene un solo tipo de error, distinto al de los otros, y todos
compilan sin advertencias. Para cada uno, en este orden:

1. Córranlo con `build/hunt/nombre`, y con `valgrind --leak-check=full build/hunt/nombre_vg`.
2. Lean el informe y **dibujen** el bloque y los punteros en el momento del error.
3. Escriban la explicación en `hunt/report.md`.
4. Corrijan el programa. La salida correcta debe ser la que el programa quería dar: en
   `route_backup.c`, por ejemplo, el respaldo debe conservar el nombre original.

Un programa puede parecer correcto con una herramienta y no con la otra. Revisen las dos
antes de decidir que no tiene errores.

### Parte 5: un arreglo que crece (40 minutos)

En `int_array.c`, escriban `int_array_new`, `int_array_push` e `int_array_free`, según
`int_array.h`, y después `int_array_read_file`. Agreguen sus casos en `array_tests.c`.

```sh
make lab && build/lab/array_tests
echo lab/data/numbers.txt | build/lab/sum_file
```

Cuando pasen, corran `make test-lab`. Las pruebas comprueban los programas corregidos, pero
no leen `hunt/report.md`.

Si no alcanza el tiempo, `int_array_read_file` queda para antes de la próxima clase.
