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 被调用时,它将复制整个 dangerousStringbuffer,导致溢出。这将覆盖 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 对象,可能会发生浅拷贝,导致多个对象共享同一块内存,这可能会引起问题。

posted @ 2024-08-12 13:45  Q星星  阅读(177)  评论(0)    收藏  举报