在 C++ 中 cin 时内存损坏
Memory corruption when cin in c++
我有班级"学生.cpp"
#include <iostream>
#include "student.h"
using namespace std;
void student::setMarks(int m1, int m2) {
mark1 = m1;
mark2 = m2;
};
void student::setName(char *n) {
name = n;
};
int student::calc_media(void){
return (mark1+mark2)/2;
};
void student::disp(void){
cout << "Student:" << name << " n media:"<< calc_media() <<"n";
};
student::student(){
mark1 = 0;
mark2 =0;
name = "";
};
头文件 "student.h":
ifndef CLASY_STUDENT_H
#define CLASY_STUDENT_H
#endif //CLASY_STUDENT_H
class student{
char *name;
int mark1, mark2;
public:
void setName(char *n);
void setMarks(int m1, int m2);
void disp(void);
int calc_media(void);
student();
};
和"主要.cpp":
#include <iostream>
#include "student.h"
using namespace std;
int main() {
student s;
char* n;
int m1, m2;
cout << "Enter name:";
cin>> n;
cout << "Enter marks of two subjects:";
cin>> m1;
cin>> m2;
s.setName(n);
s.setMarks(m1, m2);
s.disp();
return 0;
}
我正在运行这个 usign Clion 和 Cmake 是:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(SOURCE_FILES main.cpp student.cpp student.h student.cpp student.h)
但是当我运行时,它会询问名称,但是当我键入某些内容时,我遇到了内存碎片错误。怎么了?顺便说一下,有人可以告诉我它看起来是否适合C++?我正在尝试从java切换到c ++。
char* n;
...
cin>> n;
n
是一个指针,应该指向特定的内存。但你从来没有设置过它。因此,它具有一些未定义的值,将谁知道的位置指向您最终试图覆盖的某个内存。很可能是不允许覆盖的内存,从而导致段错误。
如果您还不了解手动内存管理,请不要尝试使用 char*
(一旦您了解了,您就会明白为什么不这样做)。使用 std::string
。
乍一看,您几乎可以在任何地方用std::string
替换char*
(只要您#include <string>
)。
与其他人所说的类似,您的变量n
是一个未初始化的指针。 指针,顾名思义,只是内存中特定位置的路标 - 告诉 CPU"转到变量 x 的此内存位置"。
假设你有一个整数变量var
,声明如下:
int var;
该变量占用内存,您可以为其分配如下值:
var = 5;
您还可以声明指向整数的指针,如下所示:
int * var_ptr;
现在假设var_ptr
指向一个有效的整数,我可以像这样为它分配一个值:
*var_ptr = 5;
这说"将数字 5 放在 var
指向的内存位置"。 但是,如果var_ptr
尚未初始化,那么它将指向内存中的随机位置,该位置可能会覆盖重要内容,或尝试写入导致保护错误的受保护内存地址(段错误)。这就是代码中发生的情况。
要初始化var_ptr
指向 var
的地址,我们可以这样做:
var_ptr = &var;
与号是"地址"运算符 - 它说"不要给我var
的值,而是给我存储var
的内存位置的地址"。
因此,为了防止出现问题,您必须将n
初始化到某个有效的内存位置,以便能够安全地写入一些数据。
有几种方法可以做到这一点。 正如@Stefan指出的,您可以将n
声明为字符数组:
char n[20];
正如@BobTFish指出的那样,您需要某种方法来确保您的输入不超过数组的大小(在本例中为 20 字节)。 解决方案是 std::cin.width(20)
.
正如@BobTFish也提到的,你也可以使用 std::string
,像这样:
std::string n;
std:cin >> n;
std::string
对象将自动处理内存分配。
如果你真的必须使用char *
,你可以取一个char
数组的地址(这里我取数组第一个元素的地址):
char n_array[20];
char *n = &n_array[0];
std::cin.width(20);
std::cin >> n;
您还可以使用动态内存分配:
char *n = new char[20];
std::cin.width(20);
std::cin >> n;
delete n;
请注意,如果使用动态内存分配,则必须使用delete
释放内存,否则将出现内存泄漏。 局部变量(如数组)在堆栈上分配,因此在函数返回时自动释放。 出于这个原因,以及动态内存分配的开销,在这里使用它将是疯狂的。
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 正在调试 malloc():新内存损坏
- 仅特定内核计数上的 MPI 内存损坏
- C++程序错误:malloc():内存损坏
- 调用std::函数成员时内存损坏
- C++ 内存损坏检测
- 由于标头中的 #define 不匹配而导致内存损坏
- C STD ::线程中的种族状况或内存损坏
- malloc()内存损坏仅通过为特定数量编写int数组
- 字符串标记化期间的内存损坏
- 从检测到 glibc 正常退出 - malloc():内存损坏
- 放置在外部 DLL 中的类中的字符串数据的内存损坏
- std :: string ::擦除会导致内存损坏
- 编译器如何检测内存损坏
- mix_playMusic导致内存损坏
- 在使用新操作员和C 中的结构的调用构造函数时,获得内存损坏(Malloc)
- 两个内联程序集调用与一个内联程序集调用中的内存损坏?
- 如何调试不确定内存损坏?
- 增强Dijkstra代码会导致片段内存损坏
- 内存损坏从vb.net调用c dll