[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[fol] 正常にcalloc/malloc出来るが書き込み出来ない


いつもお世話になっております。
LinuxまたはCのメモリ管理について何か情報をお持ちの方がいらっしゃったら、

ポインタでも結構ですから御教授頂ければ幸いです。

問題:
構造体の配列に割り当てられたメモリ領域の全てのバイトを0で初期化する
ルーチンがあります。
ルーチン単体のテストでは割り当て/読み書き共全く問題なく動作するのに、
他のルーチンと結合した後、メモリ領域を割り当てて、(割り当ては成功
しているように見える)書き込もうとするとSegmentation faultを起こします。

システムはTurboLinux4.2で、libcなどは変更していません。

Segmentation faultを起こした時、perror()はSuccessを表示し、返される
メモリもNULLではありません。
ソフトが起動してから最初に行なわれるmalloc/callocなので、原因の特定に
苦しんでいます。

思い当たる点といえば、他のファイル中でstatic constな変数を多用している
とか、(恐らく合計は100KB未満でしょう。なお、大きな配列はmallocで確保
するようにしています)pthreadライブラリをリンクしている位です。
(ただしpthread関連の操作は該当ルーチンを呼び出した後で行なわれます)


なお、あまり参考にはならないと思いますが、ソフトを構成するソースファイル
の
合計は100KB程度です。そのうちstatic constな定数を設定しているヘッダファ
イルの合計は39KB程度です。

Apacheのソースを検索するとsbrkを使ってデータ領域を拡張しているようです
が、
メモリ使用量も大きくなると、これらの使用を検討すべきなのでしょうか。
#もしくはヒープ領域を拡張するとか?

もっとも、何時どの様にsbrk/brkを使うのかを理解しておりませんが…。

ソースの抜粋を以下に書いておきます。重ねて言いますが、単体では問題なく
動作します。

**********************ソースから抜粋****************************
typedef struct {
  int mimenum;
  int length;
  char mimetype[64];
  char extension[8];
  int count;
} _MIMETYPE; /* Total 84 Bytes */

static _MIMETYPE *_mimetypes;

main(){
....

  /* この時点で
     getrlimitによるmallocあるいはcalloc直前の情報
     RLIMIT_STACK  rlim_cur:    8388608, rlime_max: 2147483647
     RLIMIT_MEMORY rlim_cur: 2147483647, rlime_max: 2147483647
   */

  _mimetypes = (_MIMETYPE *)calloc(sizeof(_MIMETYPE), 512); /* 84 * 512
= 43008Bytes */
  if (_mimetypes == NULL){
    exit(-1); /* 何故か割り当ては成功している。失敗はしたことがない */
  }
  perror("memory allocate :");
  mimetypes_load();
...
}

/* 0バイト目の初期化で失敗する模様 */
void mimetypes_load(){
  int i;
  char *tmp;

  /* この時点で _mimetypes は 0x805a860(例) を指している */
  memset((void*)_mimetypes, 0, sizeof(_MIMETYPE)* 512); /* 単体ではOK */

あるいは
  tmp = (char *)_mimetypes;
  for(i = 0; i < sizeof(_MIMETYPE)*512; i++){
    tmp[i] = 0; /* i = 0でSIGSEGVを起こす。単体のテストでは問題なし */
  }

またあるいは、正攻法で
  for(i = 0; i < 512; i++){
    _mimetypes[i].mimenum = 0; /* i = 0で失敗する。単体のテストでは問題
なし */
    _mimetypes[i].length = 0;
    _mimetypes[i].extension[0] = 0;
    _mimetypes[i].count = 0;
  }
}

この情報があなたの探していたものかどうか選択してください。
yes/まさにこれだ!   no/違うなぁ   part/一部見つかった   try/これで試してみる

あなたが探していた情報はどのようなことか、ご自由に記入下さい。特に「まさにこれだ!」と言う場合は記入をお願いします。
例:「複数のマシンからCATV経由でipmasqueradeを利用してWebを参照したい場合の設定について」
Follow-Ups: