C++ c++;-由64个ASCII字符组成的字符串溢出malloc(64*sizeof(char))
如果我提供了一个长度为64个字符的十六进制字符串(即:26C8D8AB82B027808A371BC46EA789364AB8419F2B17EADFE955CBE5C6369011),即使我为其分配了64*sizeof(char)字节,下面的代码也会引发一个错误,这应该足够了:C++ c++;-由64个ASCII字符组成的字符串溢出malloc(64*sizeof(char)),c++,visual-c++,memory-management,console-application,C++,Visual C++,Memory Management,Console Application,如果我提供了一个长度为64个字符的十六进制字符串(即:26C8D8AB82B027808A371BC46EA789364AB8419F2B17EADFE955CBE5C6369011),即使我为其分配了64*sizeof(char)字节,下面的代码也会引发一个错误,这应该足够了: char* username = (char*)malloc(64 * sizeof(char)); std::cin >> username; free(username); 释放分配的内存时,在第三行
char* username = (char*)malloc(64 * sizeof(char));
std::cin >> username;
free(username);
释放分配的内存时,在第三行抛出错误:
CRT检测到应用程序在堆结束后写入内存
缓冲区
63个字符或更少时不会出现这种情况。有人能告诉我为什么仅仅64*sizeof(char)是不够的,为什么在释放内存时会抛出错误,而不是在…C字符串以NULL结尾之前 你没有给终结者留下空间 释放内存时会检测到错误,因为该函数在对象后查看填充,发现对象已损坏。如果禁用内存调试,则可能不会进行任何检查(甚至可能没有填充),并且这种错误可能不会被检测到,直到它丢弃完全不相关的数据段 如果您已经知道确切的长度,并且不需要使用终止符来标记端点,则可以使用
cin.read(username, 64);
这不会存储终止符,也不会读取超过(或少于)64个字符的输入,因此不会溢出。C字符串以NULL结尾 你没有给终结者留下空间 释放内存时会检测到错误,因为该函数在对象后查看填充,发现对象已损坏。如果禁用内存调试,则可能不会进行任何检查(甚至可能没有填充),并且这种错误可能不会被检测到,直到它丢弃完全不相关的数据段 如果您已经知道确切的长度,并且不需要使用终止符来标记端点,则可以使用
cin.read(username, 64);
这不会存储终止符,也不会读取超过(或少于)64个字符的输入,因此不会溢出。C样式字符串必须比您尝试输入的字符数多包含一个
字符,为终止空字符留出空间。C样式字符串必须比您尝试输入的字符数多包含一个字符,才能为终止空字符留出空间。您忽略了字符串末尾的NUL char('\0'
)
您应该为最大长度为64的字符串分配65个字节。您忽略了字符串末尾的NUL CHAR('\0'
)
你应该为一个长度为64的字符串分配65个字节:@ TimTrasubanger-STD::MALOC当然是C++…但是你是对的,如果没有很好的理由(例如需要将分配所有权传递给C代码),就不应该使用它。@TimStraubinger这是一样的,new[]和free()给出了相同的结果。但是,Delete不会抛出错误。但是谢谢你的建议。@TimStraubinger…什么<代码>新建
和删除
也不应被推荐用于一般用途,因为stdlib提供了许多安全类,可以处理动态分配,因此用户不必这样做。多态性也不需要动态分配,这就是我假设您试图用“oop风格的对象”(如果我听过的话,这是重言式的);只需要一个指针或引用,目标可以在堆栈上。如果你打算向一个新用户推荐东西,推荐好东西。@underline\u d:我认为蒂姆在区分POD(普通的旧数据)和“对象”,前者可以安全地使用malloc()
,后者具有非平凡的结构,malloc()
给出的结果不是有效的对象。多态性不是问题的一部分。@MikeMouawad:你不知道关于抛出错误的说法有多准确。这主要是C++代码在<代码> MALLC/<代码>和<代码>新< /C>之间的区别(除了调用非平凡的旧数据类型的CTOR/Dor)。如果失败,将抛出异常。@ TimStrubIngSt::MALOC肯定是C++…但是你是对的,如果没有很好的理由(例如需要将分配所有权传递给C代码),就不应该使用它。@TimStraubinger这是一样的,new[]和free()给出了相同的结果。但是,Delete不会抛出错误。但是谢谢你的建议。@TimStraubinger…什么<代码>新建
和删除
也不应被推荐用于一般用途,因为stdlib提供了许多安全类,可以处理动态分配,因此用户不必这样做。多态性也不需要动态分配,这就是我假设您试图用“oop风格的对象”(如果我听过的话,这是重言式的);只需要一个指针或引用,目标可以在堆栈上。如果你打算向一个新用户推荐东西,推荐好东西。@underline\u d:我认为蒂姆在区分POD(普通的旧数据)和“对象”,前者可以安全地使用malloc()
,后者具有非平凡的结构,malloc()
给出的结果不是有效的对象。多态性不是问题的一部分。@MikeMouawad:你不知道关于抛出错误的说法有多准确。这主要是C++代码在<代码> MALLC/<代码>和<代码>新< /C>之间的区别(除了调用非平凡的旧数据类型的CTOR/Dor)。如果失败,将抛出异常。ASCII字符的名称是NUL,而不是NULL(这是C定义的NULL指针)。我这么说是因为在实际代码中使用NULL作为字符串结尾很不幸是常见的(也是错误的)。是的,字符是'\0'
。。。但当然,如果编写“字符串文字”
,它会自动追加,因此像这样包含它将是毫无意义和浪费的。相反,它是供我使用的