2017-01-26 55 views
-3

我得到一個分段錯誤與此代碼:分割故障(核心轉儲)動態數組

這裏是標題:

using namespace std; 

class Dynamic_array { 
public: 
    Dynamic_array(); 
    Dynamic_array(Dynamic_array &); 
    Dynamic_array &operator=(Dynamic_array &); 
    ~Dynamic_array(); 

    void print_state(void); 
    int get_size(void); 

    int& operator[](int); 

    void insert(int, int); 
    void insert(Dynamic_array &, int); 

    void remove(int); 
    void remove(int, int); 

    class Subscript_range_exception { 
    }; 
private: 
    enum { 
     BLOCK_SIZE = 5, 
    }; 

    class Block { 
    public: 
     int size; 
     int a[BLOCK_SIZE]; 
     Block* next_p; 
    }; 

    class Block_position { 
    public: 
     Block* block_p; 
     Block* pre_block_p; 
     int i; 
    }; 

    Block_position find_block(int i); 
    void insert_blocks(Block *, Block *); 
    void remove_blocks(Block *, Block *, Block *); 
    Block * copy_blocks(Block *); 
    void delete_blocks(Block *); 

    int size; 
    Block* head_p; 
}; 

和我的代碼的其餘部分。它在塊的大小爲1時起作用。當大小大於1時它會引發段錯誤。

#include <iostream>          //- 
#include <string.h>          //- 
#include "dynamic_array.h"         //- 
               //- 
using namespace std;          //- 
               //- 
// ********** public functions **********       //- 
int main(){ 
    Dynamic_array d; 
    d.insert(1,0); 
    d.insert(3,1); 
    d.insert(5,2); 
    d.insert(7,3); 
    d.insert(9,4); 
    d.insert(11,5); 
    d.print_state(); 

    cout << "********** remove(int i)" << endl; 

    cout << "********** case 1: range error" << endl; 
    try { 
     d.remove(-1); 
    } catch (Dynamic_array::Subscript_range_exception) { 
     cout << "exception caught at -1" << endl; 
    } 
    try { 
     d.remove(6); 
    } catch (Dynamic_array::Subscript_range_exception) { 
     cout << "exception caught at 6" << endl; 
    } 

    cout << "********** case 2: block size == 1" << endl; 
    d.remove(5); 
    d.print_state(); 

    cout << "********** case 3: block size > 1" << endl; 
    cout << "***** remove right element" << endl; 
    d.remove(4); 
    d.print_state(); 

    cout << "***** remove left element" << endl; 
    d.remove(0); 
    d.print_state(); 
} 
               //- 
Dynamic_array::Dynamic_array() {        //- 
    head_p = NULL;          //- 
    size = 0;          //- 
}            //- 
               //- 
Dynamic_array::Dynamic_array(Dynamic_array & d) {      //- 
}            //- 
               //- 
Dynamic_array &Dynamic_array::operator=(Dynamic_array & d) {     //- 
    return *this;          //- 
}            //- 
               //- 
Dynamic_array::~Dynamic_array() {        //- 
}            //- 
               //- 
void Dynamic_array::print_state(void) {        //- 
    cout << "size:" << size << endl;       //- 
    for (Block * p = head_p; p != NULL; p = p->next_p) {     //- 
     cout << "\tsize:" << p->size << " elements:";     //- 
     for (int i = 0; i < p->size; i++) {      //- 
      cout << p->a[i] << ' ';       //- 
     }          //- 
     cout << endl;         //- 
    }           //- 
}            //- 
               //- 
int Dynamic_array::get_size(void) {        //- 
    return size; 
}            //- 
               //- 
int& Dynamic_array::operator[](int i) {        //- 
    // check i for range error        //- 
    if (i < 0 || i >= size) {        //- 
     throw Subscript_range_exception();      //- 
    }           //- 
               //- 
    // find target block and index        //- 
    Block_position position = find_block(i);      //- 
               //- 
    // return element at index i        //- 
    return position.block_p->a[position.i];       //- 
}            //- 
               //- 
void Dynamic_array::insert(int x, int i) {       //- 
    // case 1: range error         //- 
    if (i < 0 || i > size) {        //- 
     throw Subscript_range_exception();      //- 
    }           //- 
               //- 
    // case 2: empty array         //- 
    if (size == 0) {         //- 
     // create linked list consisting of a single new block    //- 
     Block * new_block_p = new Block;      //- 
     new_block_p->size = 1;        //- 
     new_block_p->a[0] = x;        //- 
     new_block_p->next_p = NULL;       //- 
               //- 
     // insert new block        //- 
     insert_blocks(NULL, new_block_p);      //- 
               //- 
     // update total size        //- 
     size++;          //- 
               //- 
     return;          //- 
    }           //- 
               //- 
    // find target block and index        //- 
    Block_position position = find_block(i);      //- 
               //- 
    // case 3: non-empty array; new block not needed     //- 
    if (position.block_p->size < BLOCK_SIZE) {      //- 
     // shift block array right       //- 
     for (int j = position.block_p->size; j > position.i; j--) {   //- 
      position.block_p->a[j] = position.block_p->a[j-1];   //- 
     }          //- 
               //- 
     // assign x         //- 
     position.block_p->a[position.i] = x;      //- 
               //- 
     // update array and block size       //- 
     size++;          //- 
     position.block_p->size++;       //- 
               //- 
    // case 4: non-empty array; new block needed      //- 
    } else {          //- 
     // create new block        //- 
     Block * new_block_p = new Block;      //- 
     new_block_p->size = 1;        //- 
     new_block_p->next_p = NULL;       //- 
               //- 
     // case 4.a: insert x into old block      //- 
     if (position.i < BLOCK_SIZE) {       //- 
      // copy last array element to new block     //- 
      new_block_p->a[0] = position.block_p->a[BLOCK_SIZE-1];   //- 
               //- 
      // shift old block array right      //- 
      for (int j = position.block_p->size-1; j > position.i; j--) {  //- 
       position.block_p->a[j] = position.block_p->a[j-1];  //- 
      }         //- 
               //- 
      // assign x into old block      //- 
      position.block_p->a[position.i] = x;     //- 
               //- 
     // case 4.b: insert x into new block      //- 
     } else {         //- 
      new_block_p->a[0] = x;       //- 
     }          //- 
               //- 
     // update total size        //- 
     size++;          //- 
               //- 
     // insert new block into linked list      //- 
     insert_blocks(position.block_p, new_block_p);     //- 
    }           //- 
}            //- 
               //- 
void Dynamic_array::insert(Dynamic_array &p, int i) {      //- 
    // case 1: range error         //- 
    // case 2: parameter array empty       //- 
    // case 3: array empty         //- 
    // find target block and index        //- 
    Block_position position = find_block(i);      //- 
    // case 4: array non-empty; new blocks not needed     //- 
    // case 5: array non-empty; new blocks needed      //- 
     // copy p         //- 
     Block * copy_p = copy_blocks(p.head_p);      //- 
     // case 5.a: insert position at start of block     //- 
     // case 5.b: insert position at middle of block     //- 
     // case 5.c: insert position after end of block     //- 
     // update total size        //- 
}            //- 
               //- 
void Dynamic_array::remove(int i) {        //- 
    // case 1: range error         //- 
    if (i < 0 || i >= get_size()) {        //- 
     throw Subscript_range_exception();      //- 
    } 
    Block_position index = find_block(i); 
    cout << "Position : " << index.i << endl; 
    // find target block and index        //- 
    // case 2: block size == 1        //- 
    if(index.block_p->size == 1) { 
     remove_blocks(NULL,index.block_p,index.block_p); 
    } 
    // case 3: block size > 1        //- 
    else if(index.block_p->size > 1) { 
     cout << "made it " << endl; 
     for (int j = index.i; j < BLOCK_SIZE-1; ++j){ 
      index.block_p->a[j] = index.block_p->a[j + 1]; 
     } 
     index.block_p->size--; 
    } 
    // update total size         //- 
    size--; 
}            //- 
               //- 
void Dynamic_array::remove(int start, int end) {      //- 
}            //- 
               //- 
// ********** private functions **********       //- 
               //- 
// purpose           //- 
// return b where          //- 
//  if i < size         //- 
//   b.block_p->a[b.i] is the ith element overall    //- 
//  else          //- 
//   b.block_p->a[b.i-1] is the i-1st element overall   //- 
//            //- 
//  if b.block_p == head_p        //- 
//   b.pre_block_p is NULL       //- 
//  else          //- 
//   b.pre_block_p points to block preceding b.block_p   //- 
// preconditions          //- 
// i in [1..size]          //- 
Dynamic_array::Block_position Dynamic_array::find_block(int i) {    //- 
    Block_position position;        //- 
               //- 
    // scan Block list         //- 
    position.i = i;          //- 
    position.pre_block_p = NULL;        //- 
    for (position.block_p = head_p;        //- 
    position.block_p != NULL;        //- 
    position.block_p = position.block_p->next_p) {      //- 
     // found in current block       //- 
     if (position.i < position.block_p->size) {     //- 
      break;         //- 
     }          //- 
               //- 
     // special case: insert just after last element     //- 
     if (i == size && position.block_p->next_p == NULL) {    //- 
      break;         //- 
     }          //- 
               //- 
     // not found yet: advance       //- 
     position.pre_block_p = position.block_p;     //- 
     position.i -= position.block_p->size;      //- 
    }           //- 
               //- 
    return position;         //- 
}            //- 
               //- 
// purpose           //- 
// create a new linked list which is a copy of the list pointed to p   //- 
// return a pointer to the head of the new linked list     //- 
// preconditions          //- 
// p is the head of a possibly empty linked list of blocks     //- 
Dynamic_array::Block * Dynamic_array::copy_blocks(Block * p) {     //- 
    Block * new_head_p = NULL;        //- 
    Block * new_p;          //- 
    while (p != NULL) {         //- 
     // allocate and link in new block      //- 
     if (new_head_p == NULL) {       //- 
      new_p = new Block;       //- 
      new_head_p = new_p;       //- 
     } else {         //- 
      new_p->next_p = new Block;      //- 
      new_p = new_p->next_p;       //- 
     }          //- 
               //- 
     // copy the elements        //- 
     new_p->size = p->size;        //- 
     for (int i = 0; i < p->size; i++) {      //- 
      new_p->a[i] = p->a[i];       //- 
     }          //- 
               //- 
     // advance         //- 
     p = p->next_p;         //- 
    }           //- 
               //- 
    // terminate new list         //- 
    if (new_head_p != NULL) {        //- 
     new_p->next_p = NULL;        //- 
    }           //- 
               //- 
    return new_head_p;         //- 
}            //- 
               //- 
// purpose           //- 
// insert the list headed by src_p into the list headed by head_p    //- 
// if dst_p is NULL         //- 
//  insert the list at the start of the list headed by head_p   //- 
// else           //- 
//  insert the list just after block dst_p      //- 
// preconditions          //- 
// list headed by src_p is non-empty       //- 
// list headed by src_p has no blocks in common with the list headed by head_p  //- 
void Dynamic_array::insert_blocks(Block * dst_p, Block * src_p) {    //- 
    // find the last block in the list headed by src_p     //- 
    Block * p = src_p;         //- 
    while (p->next_p != NULL) {        //- 
     p = p->next_p;         //- 
    }           //- 
               //- 
    // insert at head         //- 
    if (dst_p == NULL) { // insert at head       //- 
     p->next_p = head_p;        //- 
     head_p = src_p;         //- 
               //- 
    // insert after dst_p         //- 
    } else { // insert after dst_p        //- 
     p->next_p = dst_p->next_p;       //- 
     dst_p->next_p = src_p;        //- 
    }           //- 
}            //- 
               //- 
// purpose           //- 
// remove the blocks pointed to by start_p and end_p, and all the blocks between  //- 
// preconditions          //- 
// start_p and end_p point to blocks in the list headed by head_p    //- 
// end_p points to either the same block as start_p or a block to its right  //- 
// if start_p == head_p         //- 
//  pre_start_p == NULL        //- 
// else           //- 
//  pre_start_p points to the block immediately preceding start_p   //- 
//            //- 
void Dynamic_array::remove_blocks(Block * pre_start_p, Block * start_p, Block * end_p) { //- 
    // release the blocks         //- 
    while (1) {          //- 
     // release start_p        //- 
     Block * p = start_p->next_p;       //- 
     delete start_p;         //- 
               //- 
     // advance         //- 
     if (start_p == end_p) {        //- 
      break;         //- 
     } else {         //- 
      start_p = p;        //- 
     }          //- 
    }           //- 
               //- 
    // link left and right sublists        //- 
    if (pre_start_p == NULL) {        //- 
     head_p = end_p->next_p;        //- 
    } else {          //- 
     pre_start_p->next_p = start_p->next_p;      //- 
    }           //- 
}            //- 
+0

我們確實需要足夠的代碼來重現錯誤,最好使用盡可能少的無關代碼。 –

+3

使用調試器查看發生的位置和方式。 – Jarod42

+0

沒有足夠的上下文來回答... –

回答

2

int a [BLOCK_SIZE];

只有5個元素索引從0..4。

因此d.insert(11,5);和d.remove(5);

會拋出異常。