commit 003fd961221b10fd75960257c508b107e252bb27
parent 0cec6d691981dbb10d2d0967dd0e3302eda34586
Author: gearsix <gearsix@tuta.io>
Date: Sat, 9 Jul 2022 12:43:13 +0100
added buffree; fixed all memory leaks.
Diffstat:
M | buf.c | | | 69 | ++++++++++++++++++++++++++++++++++++++++----------------------------- |
M | buf.h | | | 4 | +++- |
M | test.c | | | 9 | +++++++-- |
3 files changed, 50 insertions(+), 32 deletions(-)
diff --git a/buf.c b/buf.c
@@ -5,43 +5,44 @@
#include <stdlib.h>
#include <string.h>
-static const size_t blksiz = BUFSIZ/sizeof(Piece);
-static Piece **nextp = NULL;
+static Piece *pieceblk = NULL; /* block of all pieces */
+static Piece **freeblk = NULL; /* ptr block to all free'd `pieceblk` items */
-static size_t pfree(Piece *p)
+static void pclean()
+{
+ free(freeblk);
+ free(pieceblk);
+}
+
+static Piece *pfree(Piece *p)
{
- static Piece **freeblk = NULL;
static size_t nblk = 0, nfree = 0;
+ static const size_t blksiz = BUFSIZ/sizeof(Piece *);
- if (!p) {
- if (!nextp && nfree > 0)
- nextp = &freeblk[--nfree];
- return nfree;
- }
+ if (!p) return (nfree == 0) ? NULL : freeblk[--nfree];
if (nfree + 1 > blksiz * nblk)
freeblk = realloc(freeblk, (++nblk * blksiz) * sizeof(Piece *));
if (!freeblk) { perror("failed to allocate freeblk"); exit(1); }
- freeblk[nfree++] = p;
- nextp = &freeblk[nfree - 1];
- return nfree;
+ return freeblk[nfree++] = p;
}
static Piece *palloc()
{
Piece *p;
- static Piece *pieceblk = NULL;
- static size_t nblk = 0, npieces = 0;
+
+ static size_t nblk = 0, nalloc = 0;
+ static const size_t blksiz = BUFSIZ/sizeof(Piece);
- if (pfree(NULL) > 0) {
- p = *nextp;
- nextp = NULL;
- } else {
- if (npieces + 1 > blksiz * nblk)
+ static int hook = 0;
+ if (hook == 0) { atexit(pclean); hook = 1; }
+
+ if ( !(p = pfree(NULL)) ) {
+ if (nalloc + 1 > blksiz * nblk)
pieceblk = realloc(pieceblk, (++nblk * blksiz) * sizeof(Piece));
if (!pieceblk) { perror("failed to allocate pieceblk"); exit(1); }
- p = &pieceblk[npieces++];
+ p = &pieceblk[nalloc++];
}
return memset(p, 0, sizeof(Piece));
@@ -65,23 +66,33 @@ static Piece *psplit(Piece *p, long int offset)
return p;
}
-struct Buf *bufinit(FILE *f)
+struct Buf *bufinit(FILE *read, FILE *append)
{
Buf *b = calloc(1, sizeof(Buf));
- b->append = tmpfile();
+ if (!read || !append) return NULL;
+
+ b->read = read;
+ b->append = append;
+
b->tail = b->pos = b->head = palloc();
-
- if (f) {
- b->read =f;
- b->pos->f = b->read;
- fseek(b->read, 0, SEEK_END);
- b->size = b->pos->len = ftell(b->read);
- }
+ b->pos->f = b->read;
+ fseek(b->read, 0, SEEK_END);
+ b->size = b->pos->len = ftell(b->read);
return b;
}
+void buffree(Buf *b)
+{
+ Piece *p = b->tail->next;
+ while (p) {
+ pfree(p->prev);
+ p = p->next;
+ }
+ free(b);
+}
+
Piece *bufidx(Buf *b, size_t pos)
{
size_t idx = b->idx, offset;
diff --git a/buf.h b/buf.h
@@ -15,7 +15,9 @@ typedef struct Buf {
struct Piece *tail, *pos, *head;
} Buf;
-Buf *bufinit(FILE *f);
+Buf *bufinit(FILE *read, FILE *append);
+
+void buffree(Buf *b);
Piece *bufidx(Buf *b, size_t pos);
diff --git a/test.c b/test.c
@@ -1,5 +1,6 @@
#include "buf.h"
#include <stdio.h>
+#include <stdlib.h>
#include <assert.h>
#include <string.h>
@@ -9,7 +10,7 @@
#define OUTBUF "hey buddy!" /* tests will aim to change INBUF to this */
Buf *b;
-FILE *in, *out;
+FILE *in, *tmp, *out;
void setup()
{
@@ -17,6 +18,8 @@ void setup()
if (ferror(in)) perror("fopen in.txt");
fputs(INBUF, in);
+ tmp = tmpfile();
+
out = fopen(OUTFILE, "w+b");
if (ferror(in)) perror("fopen out.txt");
@@ -25,8 +28,10 @@ void setup()
void setdown()
{
+ buffree(b);
fclose(out);
fclose(in);
+ fclose(tmp);
}
void print()
@@ -52,7 +57,7 @@ void test_bufinit()
{
Piece *p;
- b = bufinit(in);
+ b = bufinit(in, tmp);
assert(b->read);
assert(b->append);