当我尝试删除“z”时出现堆损坏错误。我假设z指向分配的内存,所以我很困惑为什么delete []会产生错误。
char* cpytoheap(const char* y)
{
char* x = new char;
for (int i=0; *(y+i); i++)
{
*(x+i) = *(y+i);
*(x+i+1) = '\0';
}
return x;
}
int main()
{
char* z = "asdf";
z = cpytoheap(z);
cout << z; //check that "asdf" copied correctly
delete[] z; //error doesn't occur if this is taken out
char y; //keep window open
cin >> y; //...
return 0;
}
我没有在cpytoheap中使用下标,因为练习是在不使用下标的情况下复制到免费商店。我通常会继续前进,但我觉得将来知道如何在这种情况下释放记忆可能很重要。
答案 0 :(得分:6)
您只为x
分配了1个字符。将其改为
char *x = new char[strlen(y)+1];
确保为内容分配足够的内存空间。
答案 1 :(得分:1)
您使用strdupa
分配z
,它将结果动态分配到堆栈。因此,它应该不被释放;当前函数返回时,它将自动释放。从这个意义上说,strdupa
类似于在当前函数中声明一个本地字符串变量。
您收到“堆损坏”错误,因为您的对象根本没有在堆上声明(free
查看堆栈分配的内存并且没有看到任何分配标记,因此它假定内存区域已损坏。)
此外,在任何情况下,您都不会使用delete[]
来释放从C函数分配的对象;如果您需要释放此类结果,请始终使用free
。
答案 2 :(得分:0)
您的程序有两个错误:
要了解这些问题,您可以在Windows平台上使用GNU / Linux上的valgrind或Windows上的WinDBG / PageHeap。 valgrind为您的程序生成以下报告。
mantosh@mantosh4u:~$ valgrind ./a.out
==4575== Memcheck, a memory error detector
==4575== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==4575== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==4575== Command: ./a.out
==4575==
==4575== Invalid write of size 1
==4575== at 0x400A12: cpytoheap(char const*) (pratice.cpp:10)
==4575== by 0x400A4E: main (pratice.cpp:19)
==4575== Address 0x5a08041 is 0 bytes after a block of size 1 alloc'd
==4575== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4575== by 0x4009D5: cpytoheap(char const*) (pratice.cpp:6)
==4575== by 0x400A4E: main (pratice.cpp:19)
==4575==
==4575== Invalid write of size 1
==4575== at 0x400A00: cpytoheap(char const*) (pratice.cpp:9)
==4575== by 0x400A4E: main (pratice.cpp:19)
==4575== Address 0x5a08041 is 0 bytes after a block of size 1 alloc'd
==4575== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4575== by 0x4009D5: cpytoheap(char const*) (pratice.cpp:6)
==4575== by 0x400A4E: main (pratice.cpp:19)
==4575==
==4575== Invalid read of size 1
==4575== at 0x4C2BFB4: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4575== by 0x4EC7288: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==4575== by 0x400A63: main (pratice.cpp:20)
==4575== Address 0x5a08041 is 0 bytes after a block of size 1 alloc'd
==4575== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4575== by 0x4009D5: cpytoheap(char const*) (pratice.cpp:6)
==4575== by 0x400A4E: main (pratice.cpp:19)
==4575==
==4575== Invalid read of size 1
==4575== at 0x53C8132: _IO_default_xsputn (genops.c:485)
==4575== by 0x53C6069: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1393)
==4575== by 0x53BBCDC: fwrite (iofwrite.c:45)
==4575== by 0x4EC6FD4: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==4575== by 0x4EC7296: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==4575== by 0x400A63: main (pratice.cpp:20)
==4575== Address 0x5a08041 is 0 bytes after a block of size 1 alloc'd
==4575== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4575== by 0x4009D5: cpytoheap(char const*) (pratice.cpp:6)
==4575== by 0x400A4E: main (pratice.cpp:19)
==4575==
==4575== Mismatched free() / delete / delete []
==4575== at 0x4C2A09C: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4575== by 0x400A76: main (pratice.cpp:21)
==4575== Address 0x5a08040 is 0 bytes inside a block of size 1 alloc'd
==4575== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4575== by 0x4009D5: cpytoheap(char const*) (pratice.cpp:6)
==4575== by 0x400A4E: main (pratice.cpp:19)
==4575==
asdf
q