Munmap_chunk() 错误,无法理解指针行为
Munmap_chunk() error, cannot understand pointer behavior
我正在用模板制作一个简单的排序程序,并且正在努力处理字符串大小写。
代码:
template<typename typ>
void Join_Segments(typ *tab, int begin1, int begin2, int end2, bool(*Compare)(typ arg1, typ arg2)){
typ *joined = new typ[end2-begin1+1]; // sorted elements arrray
int c1, c2, ci; // counters
for(c1=begin1, c2=begin2, ci=0; c1<begin2 && c2<=end2; ci++){
if(!Compare(tab[c1], tab[c2])){ joined[ci]=tab[c2]; c2++;}
else{ joined[ci]=tab[c1]; c1++;}
}
while(c1<begin2){joined[ci]=tab[c1]; c1++; ci++;}
while(!(c2>end2)){joined[ci]=tab[c2]; c2++; ci++;}
for(int i=0; i<(end2-begin1+1); i++) tab[begin1+i]=joined[i];
delete joined;
}
所以这对整数来说效果很好。只要我删除 "delete joined" 行,它就适用于字符串,但这对于排序大型数组非常重要。
GDB 回溯日志:
Program terminated with signal SIGABRT, Aborted.
#0 0x40022424 in __kernel_vsyscall ()
(gdb) bt
#0 0x40022424 in __kernel_vsyscall ()
#1 0x40171827 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#2 0x40174c53 in __GI_abort () at abort.c:89
#3 0x401ac993 in __libc_message (do_abort=do_abort@entry=1,
fmt=fmt@entry=0x402a9a5c "*** Error in `%s': %s: 0x%s ***\n")
at ../sysdeps/posix/libc_fatal.c:175
#4 0x401b6e7a in malloc_printerr (action=<optimized out>,
str=0x402a9a80 "munmap_chunk(): invalid pointer", ptr=0x90551d4)
at malloc.c:4996
#5 0x401b6f48 in munmap_chunk (p=<optimized out>) at malloc.c:2816
#6 0x400849df in operator delete(void*) ()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
#7 0x08049518 in Join_Segments<std::string> (tab=0x905500c, begin1=0, begin2=2,
end2=2, Compare=0x80490a6 <_GLOBAL__sub_I__Z2Nli()+8>) at scalanie.hh:11
#8 0x080491f5 in Mergesort<std::string> (tab=0x905500c, begin=0,
end=2, Compare=0x80490a6 <_GLOBAL__sub_I__Z2Nli()+8>) at scalanie.hh:32
#9 0x08048ee1 in main () at main.cpp:11
我认为这可能是由 std::string 赋值魔法引起的,但我不知道如何解决它。尝试了很多事情,比如将赋值的右侧投射到 (const typ&) 所以它会根据 that documentation 复制它,但它仍然在盲目地尝试。谁能帮我解决这个问题?
我可以提供完整的代码,但它在视觉上并不完全相同(英语不是我的母语,我在这里更改了 functions/var 名称)因此可能更难阅读。
谢谢!
您应该使用 delete[]
,因为您要删除分配给 new[]
的数组。根据标准,混合不正确的 new/delete
类型可能会导致未定义的行为,我想这就是您所看到的。
我正在用模板制作一个简单的排序程序,并且正在努力处理字符串大小写。 代码:
template<typename typ>
void Join_Segments(typ *tab, int begin1, int begin2, int end2, bool(*Compare)(typ arg1, typ arg2)){
typ *joined = new typ[end2-begin1+1]; // sorted elements arrray
int c1, c2, ci; // counters
for(c1=begin1, c2=begin2, ci=0; c1<begin2 && c2<=end2; ci++){
if(!Compare(tab[c1], tab[c2])){ joined[ci]=tab[c2]; c2++;}
else{ joined[ci]=tab[c1]; c1++;}
}
while(c1<begin2){joined[ci]=tab[c1]; c1++; ci++;}
while(!(c2>end2)){joined[ci]=tab[c2]; c2++; ci++;}
for(int i=0; i<(end2-begin1+1); i++) tab[begin1+i]=joined[i];
delete joined;
}
所以这对整数来说效果很好。只要我删除 "delete joined" 行,它就适用于字符串,但这对于排序大型数组非常重要。 GDB 回溯日志:
Program terminated with signal SIGABRT, Aborted.
#0 0x40022424 in __kernel_vsyscall ()
(gdb) bt
#0 0x40022424 in __kernel_vsyscall ()
#1 0x40171827 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#2 0x40174c53 in __GI_abort () at abort.c:89
#3 0x401ac993 in __libc_message (do_abort=do_abort@entry=1,
fmt=fmt@entry=0x402a9a5c "*** Error in `%s': %s: 0x%s ***\n")
at ../sysdeps/posix/libc_fatal.c:175
#4 0x401b6e7a in malloc_printerr (action=<optimized out>,
str=0x402a9a80 "munmap_chunk(): invalid pointer", ptr=0x90551d4)
at malloc.c:4996
#5 0x401b6f48 in munmap_chunk (p=<optimized out>) at malloc.c:2816
#6 0x400849df in operator delete(void*) ()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
#7 0x08049518 in Join_Segments<std::string> (tab=0x905500c, begin1=0, begin2=2,
end2=2, Compare=0x80490a6 <_GLOBAL__sub_I__Z2Nli()+8>) at scalanie.hh:11
#8 0x080491f5 in Mergesort<std::string> (tab=0x905500c, begin=0,
end=2, Compare=0x80490a6 <_GLOBAL__sub_I__Z2Nli()+8>) at scalanie.hh:32
#9 0x08048ee1 in main () at main.cpp:11
我认为这可能是由 std::string 赋值魔法引起的,但我不知道如何解决它。尝试了很多事情,比如将赋值的右侧投射到 (const typ&) 所以它会根据 that documentation 复制它,但它仍然在盲目地尝试。谁能帮我解决这个问题?
我可以提供完整的代码,但它在视觉上并不完全相同(英语不是我的母语,我在这里更改了 functions/var 名称)因此可能更难阅读。
谢谢!
您应该使用 delete[]
,因为您要删除分配给 new[]
的数组。根据标准,混合不正确的 new/delete
类型可能会导致未定义的行为,我想这就是您所看到的。