总结c++内存错误的典型情况

最近遇到了c++几张内存错误的几种典型情况:

1. 拷贝构造函数导致重复释放:http://blog.csdn.net/winlinvip/article/details/7663862

2. 内存越界导致错误:这个在http://blog.csdn.net/winlinvip/article/details/7822762 提到过。

3. 非虚析构函数导致内存泄漏:http://blog.csdn.net/winlinvip/article/details/7667460

4. 局部数组越界导致栈错误:http://blog.csdn.net/winlinvip/article/details/7822762 稍微提了一下。


把重现它们的代码集中放到这里:

1. 拷贝构造函数导致重复释放

#include <string.h>
#include <iostream>
using namespace std;

class MyString
{
private:
    int length;
    char* value;
public:
    MyString(const char* str = NULL){
        length = 0;
        value = NULL;
        SetString(str);
    }
    ~MyString(){
        delete[] value;
    }
public:
    void SetString(const char* str){
        if(str != NULL){
            length = strlen(str);
            value = new char[length + 1];
            memcpy(value, str, length);
            value[length] = 0x00;
        }
    }
public:
    const char* GetString(){
        return (const char*)value;
    }
};

int main(){
    MyString str("winlin");
    str = "hello world";
    cout << "expect: hello world, actual: " << str.GetString() << endl;
    sleep(5);
    return 0;
}


2. 内存越界导致错误

/**
# build the gperftools:
bash build_gperftools.memory-fence.sh
# to build:
g++ -g -O0 -c memcorrupt.cpp -o memcorrupt.o -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free; g++ memcorrupt.o -o memcorrupt -ltcmalloc_debug; ./memcorrupt
*/
#include <stdio.h>

class Connection;
class State
{
private:
    Connection* conn;
public:
    State(Connection* c) : conn(c){
    }
    virtual ~State(){
    }
    void action();
};

class Manager;
class Connection
{
private:
    State* state;
    Manager* manager;
public:
    Connection(){
        state = NULL;
    }
    virtual ~Connection(){
        if(state != NULL){
            delete state;
            state = NULL;
        }
    }
public:
    void SetManager(Manager* m){
        manager = m;
    }
    Manager* GetManager(){
        return manager;
    }
    void SetState(State* s){
        state = s;
    }
};

class Manager
{
private:
    Connection* conn;
public:
    Manager(){
        conn = NULL;
    }
    virtual ~Manager(){
    }
public:
    void Destroy(){
        if(conn != NULL){
            delete conn;
            conn = NULL;
        }
    }
    Connection* GetConnection(){
        return conn;
    }
    void SetConnection(Connection* c){
        conn = c;
        conn->SetManager(this);
    }
};

void State::action(){
    if(conn == NULL){
        return;
    }
    
    conn->GetManager()->Destroy();
    this->conn = NULL;
}

int main(int /*argc*/, char** /*argv*/){
    Manager manager;
    Connection* connection = new Connection();
    State* state = new State(connection);
    
    connection->SetState(state);
    manager.SetConnection(connection);
    
    state->action();
    
    return 0;
}


3. 非虚析构函数导致内存泄漏

/**
g++ -g -O0 use-interface.cpp -o use-interface; ./use-interface
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>

class IObject
{
public:
    virtual const char* ToString() = 0;
};

class String : public IObject
{
private:
    char* str;
public:
    String(const char* s){
        str = NULL;
        if(s != NULL){
            str = new char[strlen(s) + 1];
            strcpy(str, s);
        }
    }
    virtual ~String(){
        if(str != NULL){
            delete[] str;
        }
    }
public:
    virtual const char* ToString(){
        return str;
    }
};

void destroy(IObject* obj){
    delete obj;
}

int main(int /*argc*/, char** /*argv*/){
    while(true){
        destroy(new String("winlin"));
        usleep(1);
    }
    return 0;
}


4. 局部数组越界导致栈错误

/**
g++ -g -O0 stack-corrupt.cpp -o stack-corrupt; ./stack-corrupt
*/
#include <stdio.h>
#include <string.h>

void packet_unmarshal(char* stream, int size){
    printf("memcpy, size=%d\n", size);
    
    // decode packet from stream.
    char data[100];
    memcpy(data, stream, size);
    
    printf("memcpy finished\n");
}

void normal_opration3(){
    char stream[116];
    packet_unmarshal(stream, sizeof(stream));
    printf("normal opration3\n");
}
void normal_opration2(){
    normal_opration3();
    printf("normal opration2\n");
}
void normal_opration1(){
    normal_opration2();
    printf("normal opration1\n");
}
void normal_opration(){
    normal_opration1();
    printf("normal opration\n");
}

int main(int /*argc*/, char** /*argv*/){
    normal_opration();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

winlinvip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值