hello.c
This commit is contained in:
+10
-2
@@ -4,8 +4,11 @@
|
||||
|
||||
- **Fase 2**: buffer dinámico. La Fase 1 está cerrada en Fedora, pero falta
|
||||
probarla en Windows.
|
||||
- Paso actual: 2.3b, `escpos_buffer_append` (varios bytes: puntero `const` +
|
||||
cantidad + `memcpy`). El 2.3a ya está hecho: `buffer_reserve`, `static`, `t` en `nm`.
|
||||
- Paso actual: 2.3b. `hello.c` ya usa bien `goto cleanup` (punteros a `NULL`
|
||||
uno por línea, `result`, un solo `return`), sin avisos con gcc ni clang, y
|
||||
Valgrind limpio. Falta `escpos_buffer_append`: el parámetro con la cantidad,
|
||||
`const`, reservar `len + cantidad`, `memcpy` y el comentario de la cabecera.
|
||||
Ahora copia 1 byte (`sizeof *byte`).
|
||||
- Entorno activo: Fedora 42 nativo (gcc 15.2, clang 20, make 4.4, gdb 17,
|
||||
valgrind 3.26).
|
||||
|
||||
@@ -36,6 +39,7 @@
|
||||
`$@ $< $^`, `.PHONY`.
|
||||
- Pila y montón, `malloc`/`free`/`realloc`, `NULL`, propiedad de punteros,
|
||||
tipo opaco, `typedef`, `->`, `uint8_t`/`size_t`, qué tipo usar.
|
||||
- Liberar en caminos de error sin `defer`: patrón `goto cleanup`.
|
||||
- Depuración: *segfault* (139), `free(): invalid pointer` (134), gdb básico,
|
||||
y leer errores e informes de fugas en Valgrind.
|
||||
|
||||
@@ -76,6 +80,10 @@
|
||||
cambiaba (`buffer->cap`) o que empezaba en 0, y eso daba bucles infinitos.
|
||||
Lo resolvió siguiendo los valores vuelta a vuelta. Seguir pidiéndole trazas
|
||||
a mano.
|
||||
- Declaraciones múltiples: escribió `escpos_buffer *a, *b, *c = NULL;` creyendo
|
||||
que las tres valían `NULL` (solo la última). Lo detectó clang con
|
||||
`-Wsometimes-uninitialized`. Ahora declara una variable por línea.
|
||||
- Variables locales sin inicializar: creía que valían `NULL` como en Go.
|
||||
- Impresoras físicas: sin registrar marca y modelo.
|
||||
- Confunde puntero colgante ("se pierde") con fuga. Tampoco tenía claro por qué
|
||||
el slice viejo es seguro en Go tras `append` (el GC no libera el array viejo,
|
||||
|
||||
@@ -387,6 +387,14 @@ cleanup: /* etiqueta: destino del goto */
|
||||
}
|
||||
```
|
||||
|
||||
**Variables locales sin inicializar = basura.** En Go toda variable nace con
|
||||
su valor cero (`nil`, `0`, `""`). En C, una variable local que no inicializas
|
||||
contiene lo que hubiera antes en esa posición de la pila. Si un `goto` salta
|
||||
por encima de la línea `escpos_buffer *b = escpos_buffer_new();`, esa
|
||||
asignación no se ejecuta y `b` vale cualquier cosa. Pasarla a `free` es
|
||||
comportamiento indefinido. (Las variables **globales** y `static` sí empiezan a
|
||||
cero.)
|
||||
|
||||
Por qué funciona:
|
||||
|
||||
- Todos los punteros empiezan en `NULL`, y la función de liberar acepta `NULL`
|
||||
|
||||
+9
-6
@@ -3,12 +3,15 @@
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
int result = 1;
|
||||
const char *version = escpos_version();
|
||||
escpos_buffer *buffer = NULL;
|
||||
escpos_buffer *buffer_a = NULL;
|
||||
escpos_buffer *buffer_b = NULL;
|
||||
|
||||
printf("%s\n", version);
|
||||
|
||||
escpos_buffer *buffer = escpos_buffer_new();
|
||||
buffer = escpos_buffer_new();
|
||||
if (buffer == NULL) { goto cleanup; }
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
@@ -17,7 +20,7 @@ int main(void)
|
||||
if (err == -1) { goto cleanup; }
|
||||
}
|
||||
|
||||
escpos_buffer *buffer_a = escpos_buffer_new();
|
||||
buffer_a = escpos_buffer_new();
|
||||
if (buffer_a == NULL) { goto cleanup; }
|
||||
uint8_t data[] = {0x1B, 0x40};
|
||||
int err = 0;
|
||||
@@ -25,7 +28,7 @@ int main(void)
|
||||
err = escpos_buffer_append(buffer_a, data);
|
||||
if (err == -1) { goto cleanup; }
|
||||
|
||||
escpos_buffer *buffer_b = escpos_buffer_new();
|
||||
buffer_b = escpos_buffer_new();
|
||||
if (buffer_b == NULL) { goto cleanup; }
|
||||
uint8_t data_b[300];
|
||||
for (int i = 0; i < 300; i++)
|
||||
@@ -36,11 +39,11 @@ int main(void)
|
||||
err = escpos_buffer_append(buffer_b, data_b);
|
||||
if (err == -1) { goto cleanup; }
|
||||
|
||||
return 0;
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
escpos_buffer_free(buffer);
|
||||
escpos_buffer_free(buffer_a);
|
||||
escpos_buffer_free(buffer_b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user