![](/img/trans.png)
[英]Why sizeof works well on linux and encounter a runtime error on windows
[英]Why this code works well in Linux but failed in Windows?
我寫了一些鏈表代碼:鏈表的定義:
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中顯示一個隨機值,並且程序將崩潰,並顯示“訪問沖突讀取位置”。
我不知道這是否可以解決問題,但是我很確定您不希望為該節點使用析構函數。
當然,當操作ENTRIES
時,您會崩潰; split_them_up
函數刪除了它指向的Node
對象。
從外觀aLink
,您打算將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;}
如果鏈接很大,很容易使堆棧溢出。 遞歸是一件好事,但當運到極限時則不是。 :-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.