2016-03-27 9 views
1

を分割する場合は、次の定義の構造体のリンクリストです:実装mallocの:ヒープブロック

struct block 
{ 
/*header + block*/ 
bool freeSpace; 
block * prev; 
block * next; 
size_t size; 
char block_part[]; 
}; 

私は次のような場合に取り組んでいます:

の最初のブロックの場合私が見つけたメモリは非常に大きいので、新たに割り当てられた ブロックと別のブロックの両方に対応することができます。ブロックは2つに分割されます。新たに 割り当てブロックを保持する1つのブロックと、残りの空きブロックとを含む。

(私が必要とするサイズよりも少し大きいが、新しいブロック用に十分な大きさではない(つまり、新しいブロックのメタデータを保持するのに十分な大きさではない)ことに注意してください。ブロックの最後)

私のコードは以下の通りです。このケースを特にテストすると、私のプログラムはsegfaultでクラッシュします。誰かが問題が何であるかを見ることができますか?ありがとう。

do{ 
    if (ptr -> freeSpace && ptr -> size >= size){ 
     /*first suffient free block is found*/ 
     ptr -> freeSpace = false; 

     if (ptr -> size > size + sizeof(struct block)){ 
      /*if big enought for 'size' AND metadata of a new block, split the block*/ 
      struct block * returnPtr = memset((ptr -> block_part), 0, size); 
      struct block * added = returnPtr + size; 
      added -> size = ptr -> size - size - sizeof(struct block); 
      added -> freeSpace = true; 
      added -> prev = ptr; 
      added -> next = ptr -> next; 
      (ptr -> next) -> prev = added; 
      ptr -> next = added; 
      ptr -> size = size; 
      return returnPtr; 

      } 
     ptr -> size = size; 
     return memset((ptr -> block_part), 0, size); 

     } 
    prevPtr = ptr; 
    ptr = ptr -> next; 


}while (ptr); 
+1

十分に大きなブロックが見つからない場合は、ブロックを分割するだけですか?そして、 ' - >'の各辺のスペースを削除してください。 –

+0

分割するときではありません。大きすぎるブロックが見つかると分割されます。 @WeatherVane – Jobs

+0

開始する前に、メモリ要件にメタデータのサイズを追加することをお勧めします。 –

答えて

2

memsetはvoid *を返します。 voidポインタは自動的にコンパイラによってキャストされるため、警告は出されません(例えば、malloc-))。

struct block *returnPtr = memset((ptr->block_part), 0, size); 

なぜだろうあなたの文字にボイド指し示すポインタを格納するための複数のメンバーとの全体構造体の廃棄物メモリ?

その後、のアドレスを使用して、ポインタを無効にして、size - 番号を転送します。その後、それを割り当てられた構造体のように扱います。その結果、addedは全く割り当てられません(sizestrlen(ptr->block_part)+1より大きい場合、あなたはすでに他の人のメモリにいます)、少なくともメモリを侵害しています。このようなメモリにアクセスすると、間違ったプログラムになります。

したがって、セグメント違反が発生し、プログラムがクラッシュすることがあります。


:これまでのところ、私は誰かが、このような方法でmemset戻り値を使用して見ていません。

+0

"メモ:これまでのところ、私は誰かがmemsetの戻り値をこのように使用するのを見たことがありませんでした。" - 私はそれをたくさん読んだけど、何も間違っていませんでした。 – Jobs

+0

block * returnPtrをchar * returnPtrに変更すると、私の問題は解決しますか? – Jobs

+1

実際にchar *に変更したときは今すぐ動作します!!!!!ありがとうございました!!!!!!!!!!!!! – Jobs