【发布时间】:2013-03-28 20:48:06
【问题描述】:
我写了一些链表代码: 链表的定义:
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
被包含:
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 中显示一个随机值,并且程序会崩溃,给出“访问冲突读取位置”。
【问题讨论】:
-
它在哪里崩溃? 如果你不能回答这个问题,你可能自己还没有使用过调试器,不应该在 SO(还)上问这个问题.
-
主函数最后一行:display_and_count(ENTRIES);
-
这篇文章的代码太多了,没人会读完。您应该尝试精简它,也许在较小的测试程序中重现您的问题。
-
您确实意识到传递给
split_them_up的less和more指针是按值传递的,因此使用less = lessHead;之类的代码分配给它们对于外部调用者来说绝对没有任何意义,对吧?此外,main()泄露了分配给less和more的两个节点。最后,我不建议在包含标准标头的代码中使用less作为任何类型的变量名,因为std::less<>是库定义的比较器,必然会导致混淆或彻底的错误。 -
请用
g++ -Wall -g编译,改进代码直到没有警告,然后用gdb调试器和valgrind内存泄漏检测器调试代码;你可能有内存问题......程序显然在 Linux 上正确完成的事实并不意味着没有泄漏(或过早的free或delete)或其他一些内存问题。
标签: c++ linux windows crash linked-list