我写了一些链表代码: 链表的定义:
struct Node {
// data is used to store an integer value in this node
int data;
// a pointer points to the next node
Node* link;
// inializes the node with a 0 value in data and a null pointer in link
Node() : data(0), link(NULL) {};
// destructor release space allocated to the linked list
~Node() {delete link;}
};
显示链接列表:
void display_and_count(Node* aLink) {
cout << "Entries: ";
int nodeNumber = 0; // elements number of linked list
for(Node* iterator = aLink; iterator->link != NULL; iterator=iterator->link) {
cout << iterator->data << ", ";
nodeNumber++;
}
cout << "contans " << nodeNumber << " nodes." << endl;
}// end display_and_count
现在我编写一个函数,将一个链表拆分为两个基于阈值的LESS和MORE,并删除原始链表中的节点:
void split_them_up(Node* aLink, Node* less, Node* more, int threshold) {
Node* lessHead = less; // head of less
Node* moreHead = more; // head of more
bool isThresholdInALink = false; // store if threshold is an element of aLink
for(Node* iterator = aLink; iterator->link != NULL; iterator = iterator->link) {
if(iterator->data < threshold) {
less->data = iterator->data;
less->link = new Node;
less = less->link;
}
else if(iterator->data > threshold) {
more->data = iterator->data;
more->link = new Node;
more = more->link;
}
else {
isThresholdInALink = true;
}
} // end for(Node* iterator = aLink; iterator->link != NULL; iterator = iterator->link)
less = lessHead;
more = moreHead;
delete aLink;
// If threshold is an element of aLink, then the new linked list contains the only threshold.
// If threshold isn't in aLink, then the new linked list contains nothing
aLink = new Node;
if(isThresholdInALink) {
aLink->data = threshold;
aLink->link = new Node;
} // end if(isThresholdInALink)*/
} // end split_them_up
然后这是主要功能:
int main() {
Node* ENTRIES = new Node; // define a linked list
get_input(ENTRIES);
display_and_count(ENTRIES);
Node* less = new Node; // define less list
Node* more = new Node; // define more list
cout << "Enter a threshold: ";
int thd; // threshold
cin >> thd;
split_them_up(ENTRIES, less, more, thd);
cout << "Less list: " << endl;
display_and_count(less);
cout << "More list: " << endl;
display_and_count(more);
cout << "ENTRIES: " << endl;
display_and_count(ENTRIES);
}
get_input函数从用户获取一些整数,从-1到结束:
void get_input(Node* aLink) {
Node* head = aLink; // head of linked list
int capacity=1; // the capacity of intArray
int* intArray = new int[capacity]; // an array stores user input
int size=0; // actual number of elements stored in the intArray
cout << "Input some integers, -1 to end: ";
while(true) {
int input;
cin >> input;
if(input == -1) break;
if(!isContained(intArray, size, input)) {
intArray[size]=input;
size++;
// if size meets capacity, double capacity
if(size >= capacity) {
int* temp = new int[capacity];
int oldCapacity = capacity;
for(int i=0; i < oldCapacity; i++) temp[i]=intArray[i];
delete[] intArray;
capacity = 2*capacity;
intArray = new int[capacity];
for(int i=0; i < oldCapacity; i++) intArray[i]=temp[i];
delete[] temp;
} // end if(size >= capacity)
} // end if(!contained(intArray, size, input))
} // end while(true)
for(int i=0; i<size; i++) {
aLink->data = intArray[i];
aLink->link = new Node;
aLink = aLink->link;
}
delete[] intArray;
aLink = head;
} // end get_input
isContained:
bool isContained(int* array, int aSize, int n) {
for(int i=0; i<aSize; i++) {
if(array[i] == n) return true;
}
return false;
} // end isContained
在Linux系统中执行时一切正常。但是在windows中,它会在split_them_up之后在ENTRIES中显示一个随机值,程序将崩溃,从而产生“访问冲突读取位置”。
答案 0 :(得分:1)
我不知道这是否能解决问题,但我非常确定你不希望这样的析构函数用于节点。
答案 1 :(得分:0)
当然,操纵ENTRIES
时会崩溃; split_them_up
函数删除了它指向的Node
对象。
从它的外观来看,您打算将aLink
声明为指向指针,以便您可以实际更改ENTRIES
的值以指向新声明的Node
(在你泄漏的那一刻)。
或者,您可以删除子节点并重新使用aLink
,而不是删除aLink
,而是替换它:
delete aLink;
aLink = new Node;
if(isThresholdInALink) {
aLink->data = threshold;
aLink->link = new Node;
}
用这个:
delete aLink->link;
if(isThresholdInALink) {
aLink->data = threshold;
aLink->link = new Node;
} else {
aLink->data = 0;
aLink->link = NULL;
}
为什么糟糕的代码适用于Linux?猜测,新声明的Node
巧合地创建在与原始删除节点相同的位置,因此ENTRIES
意外地指向了正确的位置。
我还会评论您不需要lessHead
或moreHead
;他们没有做任何有用的事情。完全删除它们。就像aHead
一样,由于less
和more
未被声明为指针指针,因此调用函数中的值不会受split_them_up
内发生的任何事情的影响}。
附加:析构函数,
~Node() {delete link;}
如果链接很大,可能会溢出堆栈。递归是一件好事,但在极端情况下并非如此。 : - )