Merge sort logic failure in allocating memory.
我正在研究合并排序的实现,它将按歌曲的长度对列表进行排序。我已经写了以下内容,并且无法发现我的逻辑中的缺陷。这些函数不返回排序列表,而是从原始列表的中间返回一个项目列表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | vector<song> merge( vector<song> firstList, vector<song> secondList){ vector<song> outPut; int i = 0; int n = 0; while( outPut.size() < (firstList.size() + secondList.size()-1 )){ if( firstList[i].length < secondList[n].length){ outPut.push_back( firstList[i]); i++; }else{ outPut.push_back( secondList[n]); n++; } } return outPut; } vector<song> mergeSortLength( vector<song> playlist){ int scope = playlist.size()/2; vector<song> firstHalf( &playlist[0], &playlist[scope]); vector<song> secondHalf( &playlist[scope], &playlist[playlist.size()]); if ( firstHalf.size() != 1){ firstHalf = mergeSortLength(firstHalf); } if ( secondHalf.size() != 1){ secondHalf = mergeSortLength( secondHalf); } return merge( firstHalf, secondHalf); } |
如果我将while循环条件从
1 | ( outPut.size() < (firstList.size() + secondList.size() -1)){ |
到
1 | ( outPut.size() < (firstList.size() + secondList.size())){ |
列表排序成功进行到一半,直到编译器吐出:
playList(27898,0x7fff78b7b000) malloc: * mach_vm_map(size=7526769998340063232) failed (error code=3)
* error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
libc++abi.dylib: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
Abort trap: 6
我真的很感激任何人的帮助。我的眼睛因为盯着这个而变得模糊。
在merge()中,代码不检查是否已到达向量的末尾,特别是如果i>=firstlist.size()或n>=secondlist.size(),在这种情况下,将复制其他向量的其余部分。while语句的结尾不应该有-1。
vs抱怨使用&;playlist[playlist.size()]创建临时矢量,因为下标超出范围。一种可选的方法是使用begin()+index,它是一个迭代器:
1 2 3 | vector<song> firstHalf( playlist.begin()+0, playlist.begin()+scope); vector<song> secondHalf( playlist.begin()+scope, playlist.begin()+playlist.size()); |
已经过去一天了,所以发布一个固定版本以防有人感兴趣。所有的向量创建和回推都会增加大量的开销,最好只进行一次分配,然后使用迭代器或索引来处理子向量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | vector<song> merge( vector<song> firstList, vector<song> secondList){ vector<song> outPut; size_t i = 0; size_t n = 0; while( outPut.size() < (firstList.size() + secondList.size()) ){ if( firstList[i].length < secondList[n].length){ outPut.push_back( firstList[i]); if(++i >= firstList.size()){ do outPut.push_back( secondList[n]); while(++n < secondList.size()); break; } }else{ outPut.push_back( secondList[n]); if(++n >= secondList.size()){ do outPut.push_back( firstList[i]); while(++i < firstList.size()); break; } } } return outPut; } vector<song> mergeSortLength( vector<song> playlist){ size_t scope = playlist.size()/2; vector<song> firstHalf( playlist.begin()+0, playlist.begin()+scope); vector<song> secondHalf( playlist.begin()+scope, playlist.begin()+playlist.size()); if ( firstHalf.size() != 1){ firstHalf = mergeSortLength(firstHalf); } if ( secondHalf.size() != 1){ secondHalf = mergeSortLength( secondHalf); } return merge( firstHalf, secondHalf); } |
我没怎么注意到,但也许你想
1 | vector<song> secondHalf( &playlist[scope+1], &playlist[playlist.size()-1]); |
没有-1的播放列表[playlist.size()]我认为是您问题的根源,但我没有尝试过。