关于c ++:在分配内存时合并排序逻辑失败

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()]我认为是您问题的根源,但我没有尝试过。