为什么这会导致堆损坏?
Why this causing Heap corruption?
为什么这段代码在尝试删除 [] 全名变量时导致堆损坏?
#include <iostream>
#include <cstring>
#include "stdafx.h"
using namespace std;
int main() {
const int size = 255;
char* firstname = new char[size];
char* lastname = new char[size];
cin.getline(firstname, size, '\n');
cin.getline(lastname, size, '\n');
int fullnamesize = strlen(firstname) + strlen(lastname) + 2;
cout << "fullname size: " << fullnamesize;
char* fullname = new char[fullnamesize];
strcpy_s(fullname, size, firstname);
strcat_s(fullname, size, " ");
strcat_s(fullname, size, lastname);
cout << "full name: " << fullname << "\n" ;
delete[] fullname;
delete[] firstname;
delete[] lastname;
cout << "hello";
return 0;
}
我找不到这个分配有什么问题...
这是怎么回事?
它实际上在 strcpy_s 处出错了。因为 strcpy_s 首先覆盖目标缓冲区(到函数调用中指定的大小)。参见 https://msdn.microsoft.com/en-us/library/td1esda9.aspx -
The debug versions of these functions first fill the buffer with 0xFE.
To disable this behavior, use _CrtSetDebugFillThreshold.
(我承认这很微妙!)
并且您的目标缓冲区大小错误,因此您的内存被覆盖,因为您只为全名分配了足够的内存,但您传递的大小参数更大。
为什么它在 delete[] 而不是 strncpy 时崩溃?
delete[] 处的释放没有任何问题。在您到达那里之前,问题就已经发生了。
程序不知道您传入了错误的大小。但是 strcpy 函数覆盖了堆中的内存管理结构。在 delete[] 调用之前,这不会导致任何问题。 Delete 尝试使用该信息并发现它已损坏。然后你会崩溃。
在大型程序中,此类问题完全是一场噩梦。
正确的做法是什么?
使用安全字符串函数是个好主意,但您需要仔细阅读它们的手册以确保获得正确的结果。并且要更加小心你传递给他们的尺寸。
*PS。理解旧的 strcpy 和 char * 方法很重要,但在长 运行 中,为了获得健壮的代码,请研究 std::string*
为什么这段代码在尝试删除 [] 全名变量时导致堆损坏?
#include <iostream>
#include <cstring>
#include "stdafx.h"
using namespace std;
int main() {
const int size = 255;
char* firstname = new char[size];
char* lastname = new char[size];
cin.getline(firstname, size, '\n');
cin.getline(lastname, size, '\n');
int fullnamesize = strlen(firstname) + strlen(lastname) + 2;
cout << "fullname size: " << fullnamesize;
char* fullname = new char[fullnamesize];
strcpy_s(fullname, size, firstname);
strcat_s(fullname, size, " ");
strcat_s(fullname, size, lastname);
cout << "full name: " << fullname << "\n" ;
delete[] fullname;
delete[] firstname;
delete[] lastname;
cout << "hello";
return 0;
}
我找不到这个分配有什么问题...
这是怎么回事? 它实际上在 strcpy_s 处出错了。因为 strcpy_s 首先覆盖目标缓冲区(到函数调用中指定的大小)。参见 https://msdn.microsoft.com/en-us/library/td1esda9.aspx -
The debug versions of these functions first fill the buffer with 0xFE. To disable this behavior, use _CrtSetDebugFillThreshold.
(我承认这很微妙!)
并且您的目标缓冲区大小错误,因此您的内存被覆盖,因为您只为全名分配了足够的内存,但您传递的大小参数更大。
为什么它在 delete[] 而不是 strncpy 时崩溃?
delete[] 处的释放没有任何问题。在您到达那里之前,问题就已经发生了。
程序不知道您传入了错误的大小。但是 strcpy 函数覆盖了堆中的内存管理结构。在 delete[] 调用之前,这不会导致任何问题。 Delete 尝试使用该信息并发现它已损坏。然后你会崩溃。
在大型程序中,此类问题完全是一场噩梦。
正确的做法是什么?
使用安全字符串函数是个好主意,但您需要仔细阅读它们的手册以确保获得正确的结果。并且要更加小心你传递给他们的尺寸。
*PS。理解旧的 strcpy 和 char * 方法很重要,但在长 运行 中,为了获得健壮的代码,请研究 std::string*