I get a heap corruption error when I try to delete "z". I assume that z points to the allocated memory, so I'm confused as to why delete[] creates an error.
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;
}
I didn't use subscript in cpytoheap because the exercise is to copy to free store without using subscript. I would normally move on but I feel it may be important in the future to know how to free memory in this type of situation.
You only allocated 1 char for x
. Change it into
char *x = new char[strlen(y)+1];
to make sure enough memory space is allocated for the content.
You used strdupa
to allocate z
, which allocates the result dynamically on the stack . Therefore, it should not be freed ; it will automatically be deallocated when the current function returns. In that sense, strdupa
is similar to declaring a local string variable in the current function.
You get a "heap corruption" error because your object isn't declared on the heap at all ( free
looks at the stack-allocated memory and doesn't see any allocation markers, so it assumes that the memory region is corrupted).
Also, in any case, you would not use delete[]
to free an object allocated from a C function; if you need to free such a result, always use free
.
Your program have two error:
To understand these problem you can use valgrind on GNU/Linux or WinDBG/PageHeap on Windows platfrom. The following report is generated by valgrind for your program.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.