メモリ管理の改善
authorj8takagi <j8takagi@nifty.com>
Sun, 12 Dec 2010 15:34:48 +0000 (00:34 +0900)
committerj8takagi <j8takagi@nifty.com>
Sun, 12 Dec 2010 15:34:48 +0000 (00:34 +0900)
メモリ管理用に、cmem.hとcmem.hを独立/追加
不要になった領域をfree()で解放
malloc_chk時に、memsetで領域を0で埋める

16 files changed:
include/casl2.h
include/cerr.h
include/cmem.h [new file with mode: 0644]
include/word.h
src/Makefile
src/assemble.c
src/casl2.c
src/cerr.c
src/cmd.c
src/cmem.c [new file with mode: 0644]
src/exec.c
src/label.c
src/struct.c
src/token.c
src/word.c
test/unit/TEST.mk

index fa8ec3b..aee7f1e 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "word.h"
 #include "hash.h"
+#include "cmem.h"
 #include "cerr.h"
 
 #ifndef ARRAYSIZE
index ee44ee4..662cff2 100644 (file)
@@ -6,23 +6,12 @@
 #include <string.h>
 #include <assert.h>
 #include <stdbool.h>
+#include "cmem.h"
 
 #ifndef ARRAYSIZE
 #define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
 #endif
 
-/* mallocを実行し、メモリを確保できない場合は */
-/* エラーを出力して終了 */
-void *malloc_chk(size_t size, char *tag);
-
-/* callocを実行し、メモリを確保できない場合は */
-/* エラーを出力して終了 */
-void *calloc_chk(size_t nmemb, size_t size, char *tag);
-
-/* malloc_chkを実行してメモリを確保してから、 */
-/* コピーした文字列を返す */
-char *strdup_chk(const char *s, char *tag);
-
 /* エラーの構造体 */
 typedef struct {
     int num;        /* エラー番号 */
diff --git a/include/cmem.h b/include/cmem.h
new file mode 100644 (file)
index 0000000..2e7cd3c
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef YACASL2_CMEM_H_INCLUDED
+#define YACASL2_CMEM_H_INCLUDED
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdbool.h>
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
+#endif
+
+/* mallocを実行し、メモリを確保できない場合は */
+/* エラーを出力して終了 */
+void *malloc_chk(size_t size, char *tag);
+
+/* callocを実行し、メモリを確保できない場合は */
+/* エラーを出力して終了 */
+void *calloc_chk(size_t nmemb, size_t size, char *tag);
+
+/* malloc_chkを実行してメモリを確保してから、 */
+/* コピーした文字列を返す */
+char *strdup_chk(const char *s, char *tag);
+
+/* メモリがNULLの場合は解放 */
+void free_chk(void *ptr, char *tag);
+#endif
index c1efb67..7f11c5e 100644 (file)
@@ -8,6 +8,7 @@
 #include <ctype.h>
 #include <stdbool.h>
 
+#include "cmem.h"
 #include "cerr.h"
 
 /* wordのエラー定義 */
index 48254ab..ca967d9 100644 (file)
@@ -1,34 +1,38 @@
 INCLUDE = ../include
 CC = gcc
 CFLAGS = -g -Wall -I $(INCLUDE)
-HASHSRC = hash.o
-CERRSRC = cerr.o
-WORDSRC = word.o
-COMMONSRC = $(WORDSRC) $(HASHSRC) $(CERRSRC) struct.o cmd.o
-ASSRC = assemble.o token.o label.o macro.o
-EXECSRC = exec.o dump.o
+WORDOBJ = word.o
+HASHOBJ = hash.o
+CMEMOBJ = cmem.o
+CERROBJ = cerr.o
+COMMONOBJ = $(WORDOBJ) $(HASHOBJ) $(CMEMOBJ) $(CERROBJ) struct.o cmd.o
+ASOBJ = assemble.o token.o label.o macro.o
+EXECOBJ = exec.o dump.o
+COMMONHEAD = $(INCLUDE)/casl2.h $(INCLUDE)/word.h $(INCLUDE)/hash.h $(INCLUDE)/cmem.h $(INCLUDE)/cerr.h
+ASHEAD = $(INCLUDE)/assemble.h
+EXECHEAD = $(INCLUDE)/exec.h
 
 .PHONY: all clean
 
 all: ../casl2 ../comet2 ../dumpword
 
-../casl2: casl2.o $(COMMONSRC) $(ASSRC) $(EXECSRC)
+../casl2: casl2.o $(COMMONOBJ) $(ASOBJ) $(EXECOBJ)
        $(CC) $(CFLAGS) -o $@ $^
 
-../comet2: comet2.o $(COMMONSRC) $(EXECSRC)
+../comet2: comet2.o $(COMMONOBJ) $(EXECOBJ)
        $(CC) $(CFLAGS) -o $@ $^
 
-../dumpword: dumpword.o $(WORDSRC) $(CERRSRC)
+../dumpword: dumpword.o $(WORDOBJ) $(CMEMOBJ) $(CERROBJ)
        $(CC) $(CFLAGS) -o $@ $^
 
 %.o: %.c
        $(CC) -c $(CFLAGS) $<
 
-casl2.o comet2.o $(COMMONSRC) $(ASSRC) $(EXECSRC): $(INCLUDE)/casl2.h $(INCLUDE)/word.h $(INCLUDE)/hash.h $(INCLUDE)/cerr.h
+casl2.o comet2.o $(COMMONOBJ) $(ASOBJ) $(EXECOBJ): $(COMMONHEAD)
 
-casl2.o $(ASSRC): $(INCLUDE)/assemble.h
+casl2.o $(ASOBJ): $(ASHEAD)
 
-comet2.o $(EXECSRC): $(INCLUDE)/exec.h
+comet2.o $(EXECOBJ): $(EXECHEAD)
 
 TAGS: $(INCLUDE)/*.h *.c
        @if test `which etags`; then etags $^; fi
index 42ef345..6d67955 100644 (file)
@@ -470,6 +470,8 @@ bool assemble(const char *file, PASS pass)
         if(cerr->num > 0) {
             break;
         }
+        free_chk(line, "line");
+        free_chk(cmdl, "cmdl");
     }
     if(cerr->num > 0) {
         fprintf(stderr, "Assemble error - %d: %s\n", cerr->num, cerr->msg);
index 40001ea..7569f92 100644 (file)
@@ -128,7 +128,7 @@ int main(int argc, char *argv[])
     for(pass = FIRST; pass <= SECOND; pass++) {
         if(pass == FIRST) {
             create_cmdtype_code();        /* 命令と命令タイプがキーのハッシュ表を作成 */
-            asprop = malloc_chk(sizeof(ASPROP), "asprop");
+            asprop = malloc_chk(sizeof(ASPROP), "asprop"); /* アセンブル時のプロパティ用の領域確保 */
         }
         for(i = optind; i < argc; i++) {
             /* データの格納開始位置 */
@@ -155,8 +155,10 @@ int main(int argc, char *argv[])
             }
         }
         if(pass == SECOND) {
-            free_cmdtype_code();    /* 命令と命令タイプがキーのハッシュ表を解放 */
             freelabel();            /* ラベルハッシュ表を解放 */
+            free_chk(asprop->prog, "asprop.prog"); /* プログラム名を解放 */
+            free_chk(asprop, "asprop");       /* アセンブル時のプロパティを解放 */
+            free_cmdtype_code();    /* 命令と命令タイプがキーのハッシュ表を解放 */
         }
     }
     if(res == true) {
@@ -174,6 +176,7 @@ int main(int argc, char *argv[])
     if(cerr->num > 0) {
         status = -1;
     }
+    free_chk(objfile, "objfile");
     /* エラーの解放 */
     freecerr();
     return status;
index 9906739..02b6a3b 100644 (file)
@@ -1,31 +1,5 @@
 #include "cerr.h"
 
-/* mallocを実行し、メモリを確保できない場合は */
-/* エラーを出力して終了 */
-void *malloc_chk(size_t size, char *tag)
-{
-    void *p;
-
-    if((p = malloc(size)) == NULL) {
-        fprintf(stderr, "%s: cannot allocate memory\n", tag);
-        exit(-1);
-    }
-    return p;
-}
-
-/* callocを実行し、メモリを確保できない場合は */
-/* エラーを出力して終了 */
-void *calloc_chk(size_t nmemb, size_t size, char *tag)
-{
-    void *p;
-
-    if((p = calloc(nmemb, size)) == NULL) {
-        fprintf(stderr, "%s: cannot allocate memory\n", tag);
-        exit(-1);
-    }
-    return p;
-}
-
 /* エラーの初期化 */
 void cerr_init()
 {
@@ -33,18 +7,6 @@ void cerr_init()
     cerr->num = 0;
 }
 
-/* malloc_chkを実行してメモリを確保してから、 */
-/* コピーした文字列を返す */
-char *strdup_chk(const char *s, char *tag)
-{
-    assert(s != NULL);
-    char *t;
-
-    t = malloc_chk(strlen(s) + 1, tag);
-    strcpy(t, s);
-    return t;
-}
-
 /* 現在のエラー */
 CERR *cerr;
 
@@ -79,7 +41,9 @@ bool addcerrlist(int newerrc, CERR newerrv[])
 /* 現在のエラーを設定する */
 void setcerr(int num, const char *str)
 {
+    /* 現在のエラー番号を設定  */
     cerr->num = num;
+    /* 現在のエラーメッセージを設定 */
     cerr->msg = malloc_chk(CERRMSGSIZE + 1, "cerr.msg");
     if(str != NULL && strlen(str) <= CERRSTRSIZE) {
         sprintf(cerr->msg, "%s: %s", str, getcerrmsg(cerr->num));
@@ -109,9 +73,11 @@ void freecerr()
     /* エラーリストを解放 */
     while(p != NULL) {
         q = p->next;
-        free(p);
+        free_chk(p, "freecerr.p");
         p = q;
     }
+    /* 現在のエラーメッセージを解放 */
+    free_chk(cerr->msg, "cerr.msg");
     /* 現在のエラーを解放 */
-    free(cerr);
+    free_chk(cerr, "cerr");
 }
index eff58de..add169a 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -48,17 +48,23 @@ CMDTAB **cmdtype_code, **code_type;
 /* 命令と命令タイプからハッシュ値を生成する */
 unsigned hash_cmdtype(const char *cmd, CMDTYPE type) {
     HKEY *keys[2];
+    unsigned hashval;
 
     /* 命令をセット */
-    keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
+    keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[0]");
     keys[0]->type = CHARS;
-    keys[0]->val.s = strdup_chk(cmd, "keys[0].val");
+    keys[0]->val.s = strdup_chk(cmd, "keys[0].val.s");
     /* 命令タイプをセット */
-    keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
+    keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[1]");
     keys[1]->type = INT;
     keys[1]->val.i = (int)(type & 070);
+    /* ハッシュ値の計算 */
+    hashval = hash(2, keys, cmdtabsize);
+    free_chk(keys[0]->val.s, "keys[0].val.s");
+    free_chk(keys[0], "keys[0]");
+    free_chk(keys[1], "keys[1]");
     /* ハッシュ値を返す */
-    return hash(2, keys, cmdtabsize);
+    return hashval;
 }
 
 /* 命令と命令タイプがキーのハッシュ表を作成する */
@@ -112,11 +118,11 @@ void free_cmdtype_code()
         np = cmdtype_code[i];
         while(np != NULL) {
             nq = np->next;
-            free(np);
+            free_chk(np, "free_cmdtype_code.np");
             np = nq;
         }
     }
-    free(cmdtype_code);
+    free_chk(cmdtype_code, "cmdtype_code");
 }
 
 /* 命令コードからハッシュ値を生成する */
diff --git a/src/cmem.c b/src/cmem.c
new file mode 100644 (file)
index 0000000..b83c79c
--- /dev/null
@@ -0,0 +1,47 @@
+#include "cmem.h"
+
+/* mallocを実行し、0で初期化 */
+/* メモリを確保できない場合はエラーを出力して終了 */
+void *malloc_chk(size_t size, char *tag)
+{
+    void *p;
+
+    if((p = malloc(size)) == NULL) {
+        fprintf(stderr, "%s: cannot allocate memory\n", tag);
+        exit(-1);
+    }
+    return memset(p, 0, size);
+}
+
+/* callocを実行 */
+/* メモリを確保できない場合はエラーを出力して終了 */
+void *calloc_chk(size_t nmemb, size_t size, char *tag)
+{
+    void *p;
+
+    if((p = calloc(nmemb, size)) == NULL) {
+        fprintf(stderr, "%s: cannot allocate memory\n", tag);
+        exit(-1);
+    }
+    return p;
+}
+
+/* malloc_chkを実行してメモリを確保してから、 */
+/* コピーした文字列を返す */
+char *strdup_chk(const char *s, char *tag)
+{
+    assert(s != NULL);
+    char *t;
+
+    t = malloc_chk(strlen(s) + 1, tag);
+    strcpy(t, s);
+    return t;
+}
+
+/* メモリがNULLの場合は解放 */
+void free_chk(void *ptr, char *tag)
+{
+    if(ptr != NULL) {
+        free(ptr);
+    }
+}
index da6fbad..35aec47 100644 (file)
@@ -41,6 +41,7 @@ void svcin()
         sys->memory[sys->cpu->gr[1]+i] = *(buffer + i);
     }
     sys->memory[sys->cpu->gr[2]] = i + 1;
+    free_chk(buffer, "buffer");
 }
 
 /* 標準出力へ文字データを書出(SVC 2) */
@@ -347,6 +348,7 @@ bool exec()
                 val = sys->memory[val];
             }
         }
+        free_chk(errpr, "errpr");
         /* 主オペランドが1〜4の場合、第2ビットを無視 */
         if(op >= 0x1000 && op <= 0x4FFF) {
             op &= 0xFB00;
index c76c3a7..1b9b806 100644 (file)
@@ -117,8 +117,8 @@ void freelabel()
             if(np->prog != NULL) {
                 free(np->prog);
             }
-            free(np->label);
-            free(np);
+            free_chk(np->label, "np.label");
+            free_chk(np, "np");
         }
     }
 }
index 8e60601..9e3d256 100644 (file)
@@ -31,8 +31,8 @@ void reset(int memsize, int clocks)
 /* COMET II仮想マシンのシャットダウン */
 void shutdown()
 {
-    free(prog);
-    free(sys->memory);
-    free(sys->cpu);
-    free(sys);
+    free_chk(prog, "prog");
+    free_chk(sys->memory, "sys.memory");
+    free_chk(sys->cpu, "sys.cpu");
+    free_chk(sys, "sys");
 }
index b9ff352..02e304d 100644 (file)
@@ -5,60 +5,61 @@
 OPD *opdtok(const char *str)
 {
     OPD *opd = malloc_chk(sizeof(OPD), "opd");
-    char *p, *q, *sepp;
-    int sepc = ',', qcnt = 0;
+    char *p, *q, *r, *sepp;     /* pは文字列全体の先頭位置、qはトークンの先頭位置、rは文字の位置 */
+    int sepc = ',', rcnt = 0;
     bool quoting = false;
 
     opd->opdc = 0;
     if(str == NULL) {
         return opd;
     }
-    p = q = strdup_chk(str, "opdtopk.p");
+    p = q = r = strdup_chk(str, "opdtopk.p");
     do {
         /* オペランド数が多すぎる場合はエラー */
         if(opd->opdc >= OPDSIZE) {
             setcerr(117, NULL);    /* operand is too many */
             break;
         }
-        /* 先頭が「=」の場合の処理 */
-        if(*q == '=') {
-            q++;
+        /* 先頭が「=」の場合 */
+        if(*r == '=') {
+            r++;
         }
         /* 「'」の場合 */
-        if(*q == '\'') {
+        if(*r == '\'') {
             /* 「''」以外の場合はquote値を反転 */
-            if(*(q+1) != '\'' && !(p < q && *(q-1) == '\'')) {
+            if(*(r+1) != '\'' && !(q < r && *(r-1) == '\'')) {
                 quoting = !quoting;
             }
-            /* 「'」の分、文字列の長さを小さくする */
-            if(*(q+1) != '\'') {
-                qcnt++;
+            /* 文字列の長さを数える。「'」の場合は数えない */
+            if(*(r+1) != '\'') {
+                rcnt++;
             }
         }
         if(quoting == true) {
             /* 閉じ「'」がないまま文字列が終了した場合 */
-            if(*q == '\0') {
+            if(*r == '\0') {
                 setcerr(123, str);    /* unclosed quote */
                 break;
             }
-            q++;
+            r++;
         } else {
-            sepp = q + strcspn(q, ", ");
+            sepp = r + strcspn(r, ", ");
             sepc = *sepp;
             *sepp = '\0';
-            if(*p == '\0') {
+            if(*q == '\0') {
                 setcerr(121, NULL);    /* cannot get operand token */
                 break;
             }
-            if(strlen(p) - qcnt > OPDSIZE) {
+            if(strlen(q) - rcnt > OPDSIZE) {
                 setcerr(118, NULL);    /* operand length is too long */
                 break;
             }
-            opd->opdv[(++opd->opdc)-1] = strdup_chk(p, "opd.opdv[]");
-            p = q = sepp + 1;
-            qcnt = 0;
+            opd->opdv[(++opd->opdc)-1] = strdup_chk(q, "opd.opdv[]");
+            q = r = sepp + 1;
+            rcnt = 0;
         }
     } while(sepc == ',');
+    free_chk(p, "opdtok.p");
     return opd;
 }
 
index cf841ce..5f49cc4 100644 (file)
@@ -76,17 +76,18 @@ char *word2n(WORD word)
     enum {
         MAXLEN = 6,        /* WORD値を10進数で表したときの最大桁数 */
     };
-    char *p = malloc_chk(MAXLEN, "word2n.p"), *q = malloc_chk(MAXLEN, "word2n.q");
+    char *p = malloc_chk(MAXLEN, "word2n.p"), *digit = malloc_chk(MAXLEN, "word2n.digit");
     int i = 0, j;
 
     do{
         *(p + i++) = word % 10 + '0';
     } while((word /= 10) > 0);
     for(j = 0; j < i; j++) {
-        *(q + j) = *(p + (i - 1) - j);
+        *(digit + j) = *(p + (i - 1) - j);
     }
-    *(q + j + 1) = '\0';
-    return q;
+    *(digit + j + 1) = '\0';
+    free_chk(p, "word2n.p");
+    return digit;
 }
 
 /* WORD値を2進数の文字列に変換 */
@@ -98,7 +99,7 @@ char *word2bit(const WORD word)
     WORD mask = 0x8000;
     char *bit, *p;
 
-    p = bit = malloc_chk(MAXLEN + 1, "word2bit.bit");
+    bit = p = malloc_chk(MAXLEN + 1, "word2bit.bit");
     do {
         *p++ = (word & mask) ? '1' : '0';
     } while((mask >>= 1) > 0);
index 2a26dde..fbda62a 100644 (file)
@@ -11,7 +11,7 @@ SRCDIR = ../../../src
 INCLUDE = ../../../include
 CC = gcc
 CFLAGS = -g -Wall -I $(INCLUDE)
-COMMONSRC = $(SRCDIR)/word.o $(SRCDIR)/struct.o $(SRCDIR)/hash.o $(SRCDIR)/cmd.o $(SRCDIR)/cerr.o
+COMMONSRC = $(SRCDIR)/word.o $(SRCDIR)/struct.o $(SRCDIR)/hash.o $(SRCDIR)/cmd.o $(SRCDIR)/cmem.o  $(SRCDIR)/cerr.o
 ASSRC = $(SRCDIR)/assemble.o $(SRCDIR)/token.o $(SRCDIR)/label.o $(SRCDIR)/macro.o
 EXECSRC = $(SRCDIR)/exec.o $(SRCDIR)/dump.o