割り当てられたメモリを解放しようとしているときにエラーメッセージが表示される理由:ヒープの破損が検出されました。 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;
}
char *s = new char [5];
strcpy(s, "hello");
原因未定義の動作(UB)。
あなたは割り当てられた記憶の範囲を超えて書いています。 5
文字に十分なメモリを割り当てましたが、文字列には6
を含む\0
文字が含まれています。
プログラムでこのUBが発生すると、すべての賭けはオフになり、あらゆる行動が可能になります。
必要なもの:
char *s = new char [strlen("hello") + 1];
実際、理想的な解決策はstd::string
ではなくchar *
を使用することです。これらは、std::string
が回避する間違いの間違いです。また、あなたの例では、char *
の代わりにstd::string
を使用する必要はありません。
with std::string
:
new
何もする必要はありませんdelete
何もする必要はありません&std::string
でできることはすべて、char *
でできます。new char [strlen(s)];
は終了\0
文字をカウントしないため、バッファーが1文字分短すぎます。
strcpy
にはヌルターミネータが含まれます。 strlen
はしません。書く:
char *s1 = new char [strlen(s) + 1];
男から strcpy(3) :
Strcpy()関数は、srcが指す文字列を、終端のヌルバイト( '\ 0')を含めて、destが指すバッファにコピーします。 。
したがって、予約する必要があります6
バイト5
は文字列、1
NULL
バイト
char *s = new char [6];
strcpy(s, "hello");
これまでのすべての回答は、最初の割り当てまたは2番目の割り当てのいずれかに対処しています。まとめると、two変更が必要です:
char *s1 = new char [strlen(s) + 1];
...
char *s = new char [5 + 1];
どちらの場合も、文字列に十分なスペースを割り当てる必要がありますプラス終了 '\ 0'に1バイト。
他の人がすでに指摘したように、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;
}
そして、それが単に文字列をコピーしている場合:
std::string s("hello");
std::string s2(s);
char *s1 = new char [strlen(s) + 1];
を指定して、'\0'
は文字列を終了します。
最初の文字列s
は5文字しかないため、nullで終了することはできません。 "hello"
は、ヌルターミネータを含むstrcpy
によってコピーされますが、バッファがオーバーランします。 strlen
はnullで終了する必要があるため、nullが存在しない場合は問題が発生します。この行を変更してみてください:
char * s = new char [6];
さらに良いのは、std::string
からCスタイルの文字列関数-同様に効率的で、はるかに安全で使いやすいです。また、本当に使用する必要がない限り、new
とdelete
を避けるようにしてください。発生している問題は非常に一般的であり、簡単に回避できます。
S2ポインターが破損しています
strcpy(s, "hello");
Sのサイズは5であるため、strcpyには文字列ターミネーターが含まれていることを見逃しています。