【问题标题】:program breaks when allocating dynamic memory to store copy of string分配动态内存以存储字符串副本时程序中断
【发布时间】:2018-05-18 15:46:10
【问题描述】:

我正在尝试查看我的所有功能是否正常工作并且程序运行到黑屏并关闭它给我一个错误,三角形内有黄色三角形感叹号表示

“milestone2.exe 0xC0000005 中抛出异常 0x01971FD0 (ucrtbased.dll):访问冲突读取位置 0x0000000”

箭头指示 .cpp 文件 m_message = new char [strlen(str) + 1 ] 位于 void ErrorMessage::message(const char* str) at

我猜这是某种内存问题,有人知道解决方案吗?

头文件

#ifndef SICT_ERROR_H_
#define SICT_ERROR_H_
namespace sict {
    class ErrorMessage {
        char* m_message;
    public:

        ErrorMessage(const char* errorMessage = nullptr);
        ErrorMessage(const ErrorMessage& em) = delete;
        ErrorMessage& operator=(const ErrorMessage& em) = delete;
        virtual ~ErrorMessage();
        void clear();
        bool isClear() const;
        void message(const char* str);
        const char* message() const;
    };
    std::ostream& operator<<(std::ostream& ostr, ErrorMessage);
}
#endif

Cpp 文件

#include "ErrorMessage.h"
#include <iostream>
namespace sict {

    ErrorMessage::ErrorMessage(const char* errorMessage) {
        m_message = nullptr;
        message(errorMessage);
    }
    void ErrorMessage::clear() {
        delete[] m_message;
        m_message = nullptr;
    }
    void ErrorMessage::message(const char* str) {
        delete[] m_message;
        m_message = new char[strlen(str) + 1];
        strcpy(m_message, str);
    }
    const char* ErrorMessage::message() const {
        return m_message;
    }
    ErrorMessage::~ErrorMessage() {
        clear();
    }
    bool ErrorMessage::isClear() const {
        if (m_message == nullptr) {
            return true;
        }
        return false;
    }
    std::ostream& operator<<(std::ostream& ostr, ErrorMessage error) {
        if (!(error.isClear())) {
            ostr << error.message();
        }
        return ostr;
    }


}

Main.cpp

#include <iostream>
#include "ErrorMessage.h"

using namespace std;
using namespace sict;

int main() {
    ErrorMessage T("Testing Error Message Module");
    ErrorMessage e;
    int ret = 0;
    bool ok = true;
    cout << T << endl << e << endl << "isClear(): " << (e.isClear() ? "Passed!" : "Failed!") << endl;
    if (!e.isClear()) ok = false;
    cout << endl;
    cout << "===========| Long Message\r";
    for (int i = 0; i < 10000000; i++) {
        if (i % 1000000 == 0) {
            cout << "*";
            cout.flush();
        }
        e.message("Some error message that is really long long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long"
            " long  long  long  long  long  long  long  long  long  long  long  long  long");
    }
    cout << '*' << endl;
    cout << e << endl << "isClear(): " << (e.isClear() ? "Failed!" : "Passed!") << endl;
    if (e.isClear()) ok = false;
    cout << endl;

    e.message("Short Message");
    cout << e << endl << e.message() << endl << "isClear(): " << (e.isClear() ? "Failed!" : "Passed!") << endl;
    if (e.isClear()) ok = false;

    e.clear();
    cout << e << endl << "isClear(): " << (e.isClear() ? "Passed!" : "Failed!") << endl;
    if (!e.isClear()) ok = false;
    cout << endl;

    if (ok) {
        cout << "You passed all the tests!" << endl;
    }
    else {
        cout << "You did not pass all the tests" << endl;
        ret = 1;
    }

    return ret;
}

【问题讨论】:

  • 使用调试器并跟踪ErrorMessage 默认构造函数的执行。
  • 如果我可以问我该怎么做?
  • 这取决于您的平台和 IDE。 how to debug small programs上的这篇文章经常被提及..
  • 远离 C 语言通常是个好主意,即普通的 char* 字符串和像 strlen 这样的 C-API。为什么不使用std::string?它还将显着简化代码,例如自动释放资源。如果您是 C 程序员,最好擦除部分内存 :-)

标签: c++ string memory


【解决方案1】:

在你的 main() 中你有:

ErrorMessage e;

它将使用空指针调用您的构造函数:

ErrorMessage::ErrorMessage(const char* errorMessage) {
    m_message = nullptr;
    message(errorMessage);
}

然后,您的构造函数将调用 message() 并将该空指针传递给它:

void ErrorMessage::message(const char* str) {
    delete[] m_message;
    m_message = new char[strlen(str) + 1];
    strcpy(m_message, str);
}

因此,您尝试在空指针上执行 strlen()。这就是它给出段错误的原因。

【讨论】:

  • 哦,谢谢!,所以原因是因为消息被设置为 nullptr 这造成了问题。我在 message void 函数中做了 if 语句,现在它可以工作了
猜你喜欢
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 2017-07-24
相关资源
最近更新 更多