C语言存在的问题——缓冲区溢出
缓冲区溢出(Buffer Overflow)是一种常见的安全漏洞,发生在当程序尝试向一个固定长度的缓冲区写入过多数据时。这可能会导致超出缓冲区分配的内存范围,覆盖相邻内存区域的数据,从而可能引起程序崩溃或安全漏洞。
举个例子:
#include <cstring>
#include <iostream>
void vulnerableFunction(char* input) {
char buffer[10]; // 缓冲区只有10个字节
strcpy(buffer, input); // 没有检查输入长度,直接复制
}
int main() {
char dangerousString[12]; // 创建一个长度为12的字符串
strcpy(dangerousString, "Hello, World!"); // 字符串长度为12,超出了缓冲区大小
vulnerableFunction(dangerousString);
std::cout << "Program did not crash." << std::endl;
return 0;
}
在这个例子中,dangerousString 的长度为12个字节(包括最后的空字符 '\0'),而 buffer 只有10个字节。当 strcpy 被调用时,它将复制整个 dangerousString 到 buffer,导致溢出。这将覆盖 buffer 后面的内存,可能破坏返回地址或其他重要的程序状态。
我们可以使用一个 MyString 类,用来封装 C 风格的字符串。
例如:
#include<iostream>
#include<string>
using namespace std;
// 析构函数
// 在对象被销毁时调用
// MyString 封装了C风格字符串(MyString::buffer)使用字符时无需分配内存和释放内存
class MyString{
private:
// 字符型的指针
char * buffer;
public:
// 构造函数
// 常量指针
MyString(const char *initString){
if(initString != NULL){
// 分配动态内存 使用new在堆上为buffer分配内存 大小为init string的长度+1
buffer = new char[strlen(initString)+1];
// 使用strcpy将initstring复制到新分配到内存中
strcpy(buffer,initString);
}
else{
buffer = NULL;
}
}
~MyString(){
if (buffer!=NULL){
delete []buffer;
}
}
int GetLength(){
return strlen(buffer);
}
const char * GetString(){
return buffer;
}
};
int main(){
MyString sayhello("hihihiqhj");
cout << "buffer is :" << sayhello.GetLength() << endl;
cout << "String is :" << sayhello.GetString() << endl;
}
这个 MyString 类实现了基本的字符串封装功能,包括动态内存分配、复制、获取长度和获取字符串。析构函数确保了动态分配的内存在对象生命周期结束时被释放,避免了内存泄漏。然而,这个类还没有实现拷贝构造函数和赋值操作符,这意味着如果直接复制 MyString 对象,可能会发生浅拷贝,导致多个对象共享同一块内存,这可能会引起问题。
浙公网安备 33010602011771号