C++ 新建/删除和字符 *
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13247126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
c++ new/delete and char *
提问by a3dsfcv
Can anyone help me, why I'm getting an error message while trying to free the allocated memory: Heap corruption detected. CTR detected the application wrote the memory after end of heap buffer.
任何人都可以帮助我,为什么我在尝试释放分配的内存时收到错误消息:检测到堆损坏。CTR 检测到应用程序在堆缓冲区结束后写入了内存。
char *ff (char *s){
char *s1 = new char [strlen(s)];
strcpy(s1, s);
return s1;
}
int _tmain(int argc, _TCHAR* argv[])
{
char *s = new char [5];
strcpy(s, "hello");
char *s2 = ff(s);
delete []s; // This works normal
delete []s2; // But I get an error on that line
return 0;
}
回答by Alok Save
char *s = new char [5];
strcpy(s, "hello");
Causes Undefined behavior(UB).
You are writing beyond the bounds of allocated memery. You allocated enough memory for 5
characters but your string has 6
characters including the \0
.
导致未定义行为(UB)。
您正在写入超出分配内存的范围。您为5
字符分配了足够的内存,但您的字符串包含6
字符,包括\0
.
Once your program has caused this UB, all bets are off and any behavior is possible.
一旦你的程序导致了这个 UB,所有的赌注都会被取消,任何行为都是可能的。
You need:
你需要:
char *s = new char [strlen("hello") + 1];
In fact the ideal solution is to use std::string
and not char *
. These are precisley the mistakes which std::string
avoids. And there is no real need of using char *
instead of std::string
in your example.
With std::string
:
事实上,理想的解决方案是使用std::string
而不是char *
。这些正是要std::string
避免的错误。并且在您的示例中并没有真正需要使用char *
而不是std::string
。
与std::string
:
- You don't need to
new
anything - You don't need to
delete
anything & - You can do everything with
std::string
, that you do withchar *
.
- 你不需要
new
任何东西 - 你不需要
delete
任何 & - 你可以做任何事情
std::string
,你做的char *
。
回答by JohnB
new char [strlen(s)];
does not count the closing \0
character, so your buffer is too short by one character.
new char [strlen(s)];
不计算结束\0
字符,因此您的缓冲区太短了一个字符。
回答by ecatmur
strcpy
includes the null terminator; strlen
does not. Write:
strcpy
包括空终止符;strlen
才不是。写:
char *s1 = new char [strlen(s) + 1];
回答by iabdalkader
From man strcpy(3):
来自 man strcpy(3):
The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest.
strcpy() 函数将 src 指向的字符串(包括终止空字节 ('\0'))复制 到 dest 指向的缓冲区。
So you need to reserve 6
bytes 5
for the string and 1
for the NULL
byte
所以,你需要储备6
字节5
的字符串,并1
为NULL
字节
char *s = new char [6];
strcpy(s, "hello");
回答by Olaf Dietsche
All answers so far have addressed either the first or the second allocation. To sum up, there are twochanges you must make:
到目前为止,所有答案都涉及第一次分配或第二次分配。总而言之,您必须进行两项更改:
char *s1 = new char [strlen(s) + 1];
...
char *s = new char [5 + 1];
In both cases, you must allocate enough space for the string plus one byte for the terminating '\0'.
在这两种情况下,您都必须为字符串分配足够的空间,并为终止 '\0'分配一个字节。
As others already pointed out, with c++ it's easier and safer to use std::string
. No fuss with allocation and release of memory or paying attention to '\0' bytes:
正如其他人已经指出的那样,使用 C++ 使用std::string
. 无需大惊小怪的内存分配和释放或注意 '\0' 字节:
std::string ff (const std::string &s){
std::string s1(s);
// do something else with s1
return s1;
}
int main(int argc, char* argv[])
{
std::string s("hello");
std::string s2 = ff(s);
return 0;
}
and if it's just copying the string:
如果它只是复制字符串:
std::string s("hello");
std::string s2(s);
回答by ChrisW
You need to specify char *s1 = new char [strlen(s) + 1];
to make room for the '\0'
which terminates the string.
您需要指定char *s1 = new char [strlen(s) + 1];
为'\0'
终止字符串的腾出空间。
回答by Sergei Nikulov
You've corrupted s2 pointer by
你已经损坏了 s2 指针
strcpy(s, "hello");
Because s has size 5, while you've missed that strcpy includes string terminator.
因为 s 的大小为 5,而您已经错过了 strcpy 包含字符串终止符。
回答by Component 10
Your initial string s
is only five characters long so can't be null terminated. "hello"
will be copied by strcpy
including the null-terminator but you'll have overrun the buffer. The strlen
needs it to be null terminated so if the null's not there, you'll have problems. Try changing this line:
您的初始字符串s
只有五个字符长,因此不能以空字符结尾。"hello"
将通过strcpy
包含空终止符来复制,但您将溢出缓冲区。在strlen
需要它是空终止,所以如果空不在那里,你就会有问题。尝试更改此行:
char *s = new char [6];
char *s = 新字符 [6];
Better still, prefer std::string
to C style string functions - they're just as efficient and a lot safer and easier to use. Also, try to avoid new
and delete
unless you really have to use them. The problems you're getting are very common and can easily be avoided.
更好的是,更喜欢std::string
C 风格的字符串函数 - 它们同样高效,更安全,更易于使用。此外,尽量避免new
,delete
除非你真的必须使用它们。您遇到的问题非常普遍,很容易避免。