質問編集履歴

1 コードの修正

sanchu52

sanchu52 score 176

2018/03/24 22:27  投稿

分割コンパイルでエラーが出て、クリアできません。
ファイルdbg_malloc.h、dbg_malloc_p.h、dbg_malloc_sub.c,
があります。gcc -c dbg_malloc.h -o -Wall ,gcc -c dbg_malloc_p.h -o -Wall
,gcc -c dbg_malloc_sub.c -o -Wall と実行すると、
gcc -c dbg_malloc_sub.c -o -Wall で以下のエラーがでます。
何回もコードを見直したのですが、上手くいきません。
教えてください。
実行結果
naka@naka ~/sample
$ gcc -c dbg_malloc_sub.c -o -Wall
dbg_malloc_sub.c: In function 'dbg_realloc':
dbg_malloc_sub.c:29:10: error: 'dbg_memory_block_hash' undeclared (first use in this function)
  hash=&(dbg_memory_block_hash[DBG_HASH_FUNC(ptr)]);
         ^~~~~~~~~~~~~~~~~~~~~
dbg_malloc_sub.c:29:10: note: each undeclared identifier is reported only once for each function it appears in
naka@naka ~/sample
$
```ここに言語を入力
コード
メモリ管理用ライブラリ(dbg_malloc.h)
#ifndef _DBG_MALLOC_H_INCLUDED_ 
#define _DBG_MALLOC_H_INCLUDED_
#include <stdio.h>
#include <stdlib.h>   //malloc(),free()などのプロトタイプ宣言が行われている
#include <string.h>
//必要な関数のプロトタイプ宣言
void *dbg_malloc(size_t size,const char *file,int line);    //mallocの代わり
void *dbg_malloc(size_t size,const char *file,int line);   
void *dbg_calloc(size_t number,size_t size,const char *file,int line);   //callocの代わり
void *dbg_calloc(size_t number,size_t size,const char *file,int line);   
void *dbg_realloc(void *ptr,size_t size,const char *file,int line);       //reallocの代わ
void *dbg_realloc(void *ptr,size_t size,const char *file,int line);       
char *dbg_strdup(const char *str,const char *file,int line);//strdupの代わり
char *dbg_strdup(const char *str,const char *file,int line);
void dbg_free(void *ptr,const char *file,int line);       //freeの代わり
void dbg_free(void *ptr,const char *file,int line);       
//メモリ管理情報の出力用の3つの関数を宣言
void *dbg_print_alloc_count(FILE *fp);
void *dbg_print_alloc_block(FILE *fp,const char *file,int line);
void *dbg_print_all_alloc_block(FILE *fp);
#ifndef DBG_MALLOC_NOCHANGE
//DBG_MALLOC_NOCHANGEの定義/未定義を切り替えることで、  
//#defineの有効,無効を切り替える  
 
#define malloc(s)      dbg_malloc((s),__FILE__,__LINE__)
#define calloc(n,s)      dbg_calloc((n),(s),__FILE__,__LINE__)
#define realloc(p,s)      dbg_realloc((p),(s),__FILE__,__LINE__)
#define strdup(str)      dbg_strdup((str),__FILE__,__LINE__)
#define free(p)          dbg_free((p),__FILE__,__LINE__)
#endif
#endif   // _DBG_MALLOC_H_INCLUDED_
#endif   
メモリ管理用ライブラリ(dbg_malloc_p.h)
#ifndef _DBG_MALLOC_P_H_INCLUDED_ 
#define _DBG_MALLOC_P_H_INCLUDED_
#define DBG_MALLOC_NOCHANGE 
#include <time.h>
//struct memory_block構造体のメンバにtime_t型を利用しているためです
#include "dbg_malloc.h"
//#define DBG_MALLOC_NOCHANGEの定義を行ってから"dbg_malloc.h"を  
//インクルードをしている。この定義により,  
//dbg_malloc()内部のmalloc()やfree()の#define が無効になる。  
 
//ライブラリ本体で,、元のmalloc()とfree()を呼び出す必要があるため,  
//malloc()とfree()がdbg_malloc()とdbg_free()に置き換わらないように,  
//#define が無効にしている。  
 
 
//これ以降必要な構造体struct memory_count,struct memory_block,  
//struct free_countを定義している  
//ソース中でdbg_malloc()を利用している場所ごとに作成される構造体
struct memory_count{
   const char *file;       // dbg_malloc()が呼ばれたファイル名を格納する
   int line;               // dbg_malloc()が呼ばれた行番号を格納する
   int number;               // dbg_malloc()によって現在獲得されている領域の個数
                           // プログラム終了時にはこの値が0になっていないときは
                           // メモリの解放忘れがあtることを示している
   
   unsigned int alloc_count;// 過去に獲得された領域の総数
                            // 対応するdbg_malloc()が呼ばれた回数を表す
                           
   unsigned int free_count; // 過去に解放された領域の総数
                            // 対応するdbg_free()が呼ばれた回数を表す   
                           
   int size;                // 現在獲得されている領域の総サイズ
                            // プログラム終了時にはこの値が0になっている
   
   unsigned int alloc_size; // 過去に獲得された領域の総サイズ
                            // プログラム終了時にはalloc_sizeとfree_sizeの値が
                            // 等しくなっているはず。
   
   unsigned int free_size;    // 過去に解放された領域の総サイズ
                            // プログラム終了時にはalloc_sizeとfree_sizeの値が
                            // 等しくなっているはず。
   
   const char *file;       
   int line;               
   int number;                   
   unsigned int alloc_count                   
   unsigned int free_count;               
   int size;               
   unsigned int alloc_size;
   unsigned int free_size;   
   struct memory_block *block_list;
   // 現在獲得している領域のリストポインタ  
   // struct memory_block構造体のリンクリストへのポインタ  
     
   struct free_count *free_list;   
   // 過去に解放した領域のリストポインタ  
   // struct memory_free構造体のリンクリストへのポインタ  
     
   struct memory_count *prev;       
   // 前のstruct memory_countへのポインタ  
   // struct memory_count構造体のリンクリストを作るためのポインタ  
     
   struct memory_count *next;       
   // 次のstruct memory_countへのポインタ  
   // struct memory_count構造体のリンクリストを作るためのポインタ  
};
//メモリ管理用ブロック
//1回のdbg_malloc()呼び出しごとに1個作成され,  
//対応するmemory_countのblock_listメンバに接続される  
struct memory_block{
   int id;           // ID番号,メモリ領域ごとに固有の値が入る
   int size;       // 獲得したメモリのサイズ,malloc()に引数として渡される値
   time_t t;       // メモリの獲得された時刻
   
   int id;           
   int size;       
   time_t t;           
   struct memory_count *mcp;   
   // バックポインタ,自分がぶら下がっているstruct memory_count構造体への
   // ポインタ,「のれん状の付け根」へのポインタ
   // dbg_free()の呼び出しの時に,対応するstruct memory_block構造体の検索後,
   // 自分がぶら下がっているstruct memory_count構造体の付け根となる
   // struct memory_count構造体を逆引きするのに使わられる
   
   struct memory_block *prev;   
   // struct memory_count構造体からのblock_listのリンク
   // struct memory_count構造体からのリンクリストのためのprevポインタ
   // struct memory_block構造体を削除する際には,リンクリストの途中から
   // 削除するので,prevポインタを持たせる必要がある
   
   struct memory_block *prev;       
   struct memory_block *next;   
   // struct memory_countのblock_listのリンク  
   // struct memory_count構造体からのリンクリストのためのnextポインタ  
     
   struct memory_block *hash_prev;   
   // ハッシュ用のリンク  
   // struct memory_block構造体の ハッシュ用のポインタ  
   // dbg_free()によってstruct memory_block構造体を削除する際には,リンクリストの途中から  
   // 削除するので,prevポインタを持たせる必要がある  
     
   struct memory_block *hash_next;   
   // ハッシュ用のリンク
   // struct memory_block構造体の ハッシュ用のポインタ
   
       
   void *data;
   // malloc()によって確保されたメモリ領域へのポインタ  
   // dbg_malloc()呼びだし時には,必要なメモリ領域と管理領域  
   // (struct memory_block構造体用の領域)はは別々に獲得して,  
   // struct memory_block構造体のdataメンバが実際のメモリ領域を指すことになる  
};
//free()管理用のブロック
//どのmalloc()がどのfree()で解放されたかの統計情報を管理する。  
//対応するmemory_countのfree listメンバに接続される  
struct free_count{
   const char *file;       // dbg_free()が呼ばれたファイル名を格納する
   
   int line;               // dbg_free()が呼ばれた行番号を格納する
   
   unsigned int count;       // 過去に解放された領域の個数
                           // dbg_free()が呼ばれた回数
                           
   unsigned int size;       // 過去に解放された領域の総サイズ
   struct free_count *next;// 次のstruct free_countへのポインタ
   const char *file;           
   int line;               
   unsigned int count;
   unsigned int size;       
   struct free_count *next;
};   
   
//malloc()統計情報となる変数の型宣言
//関数と変数名はグローバルになってしまうため,衝突を防止する目的で,  
//dbg_という接頭語を付けている  
extern unsigned int dbg_malloc_count;    //malloc()の呼び出し回数
extern unsigned int dbg_free_count;    //free()の呼び出し回数
extern unsigned int dbg_malloc_number;    //現在のメモリ取得量
extern unsigned int dbg_malloc_size;    //現在のメモリ取得量
extern struct memory_count *dbg_memory_count_head;    //リストの先端
extern struct memory_count *dbg_memory_count_tail;    //リストの終端
//struct memory_block検索用のハッシュ
//アドレスはたぶん4バイトアラインメントされているので
//下2桁は必ず4の倍数になってしまう。
//ハッシュ,ハッシュ関数には注意すること
//dbg_free()が呼び出し時に,引数で与えられたメモリ領域に
//対応するstruct memory_block構造体を検索するために利用される
//
//
#define DBG_HASH_NUM 997   //
#define DBG_HASH_NUM 997   
#define DBG_HASH_FUNC(p)\
   ((\
   (((unsigned long int)(p) >>4) & 0xf)+\
   ((unsigned long int)(p) >>8)\
   ) %DBG_HASH_NUM )
// ハッシュ用配列
extern struct memory_block *dbg_malloc_block_hash[DBG_HASH_NUM];
//型宣言されているdbg_malloc_block_hash[]には,struct memory_block構造体の  
//リンクリスト構造体へのポインタを格納する  
//struct memory_block構造体は,struct memory_count構造体にのれん状に  
//ぶら下がっているリンクリストは別に,ハッシュ用の独立したリンクリストを  
//構築する。  
 
//ハッシュの個数文(この場合は997個)のリンクリストが存在する。  
//それらの先頭へのポインタを配列dbg_malloc_block_hash[]で管理している  
//  
// 初期化用関数のプロトタイプ宣言
void dbg_init();
#endif       //_DBG_MALLOC_P_H_INCLUDED_
ライブラリ本体 dbg_malloc_sub.c
#include "dbg_malloc_p.h"
// "dbg_malloc.h"は"dbg_malloc_p.h"からインクルードされるので
// ここではインクルードしない
void *dbg_calloc(size_t number,size_t size,const char *file,int line)
{
   void *p;
   
   p=dbg_malloc(number *size,file,line);
   
   if(p){
       memset(p,0,number *size);
   }
   return (p);
}
void *dbg_realloc(void *ptr,size_t size,const char *file,int line)
{
   void *p;
   
   struct memory_block *mbp;
   struct memory_block **hash;
   
   p=dbg_malloc(size,file,line);
   
   if((p != NULL) && (ptr != NULL)){
       hash=&(dbg_memory_block_hash[DBG_HASH_FUNC(ptr)]);
       
       for(mbp=*hash;mbp;mbp=mbp->hash_next){
           if(mbp->data==ptr) break;
       }
       if((mbp != NULL) && (size > mbp->size)){
           size = mbp->size;
       
       }
       memcpy(p,ptr,size);
       dbg_free(ptr,file,line);
   }
   return (p);
}
char *dbg_strdup(const char *str,const char *file,int line)
{
   int len;
   void *p;
   len = strlen(str)+1;
   p=dbg_malloc(len,file,line);
   
   if(p==NULL) return(NULL);
   
   memcpy(p,str,len);
   
   return (p);
}
```
  • C

    5659 questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る