简体   繁体   English

MyString.exe中0x0FC9E559(ucrtbased.dll)的未处理异常:0xC0000005:访问冲突写入位置0x00000000

[英]Unhandled exception at 0x0FC9E559 (ucrtbased.dll) in MyString.exe: 0xC0000005: Access violation writing location 0x00000000

I have a problem in my string class: "Unhandled exception in strcpy function". 我的字符串类中有一个问题:“ strcpy函数中的未处理异常”。 I do not have much experience in pointers. 我没有很多指针方面的经验。 Please give me your recommendation. 请给我您的建议。 Thank you in advance ! 先感谢您 !

IDE used: Visual Studio 2017 使用的IDE:Visual Studio 2017

Unhandled exception at 0x0FC9E559 (ucrtbased.dll) in MyString.exe: 0xC0000005: Access violation writing location 0x00000000. MyString.exe中0x0FC9E559(ucrtbased.dll)的未处理异常:0xC0000005:访问冲突写入位置0x00000000。

MyString.cpp: MyString.cpp:

#pragma warning(disable:4996)
#include "MyString.h"
#include "cstring"
#include <iostream>
using namespace std;

MyString::MyString()
{
    length = 0;
    content = NULL;
}

MyString::MyString(int length, const char* content) 
{
    this->length = length;
    this->content = new char[this->length + 1];
    strcpy(this->content, content);
}

MyString::MyString(const char* content)
{
    length = strlen(content);
    this->content = new char[length + 1];
    strcpy(this->content, content);
}

void MyString::setLength(int length) 
{
    this->length = length;
}

const int MyString::getLength() 
{
    return length;
}

void MyString::setContent(char* content) 
{
    strcpy(this->content, content); // Unhandled exception !!!
}

const char* MyString::getContent() 
{
    return content;
}

ostream& operator << (ostream& out, const MyString& string)
{

        out << "Content:\n" << string.content << "\n";
        out << "Length:\n" << string.length << "\n";

    return out;
}

const MyString operator+(MyString& string1, MyString& string2)
{
    MyString concatString;
    concatString.setLength(string1.length + string2.length);
    strcat(string1.content, string2.content);
    concatString.setContent(string1.content);

    return concatString;
}

MyString::~MyString()
{
    delete[] content;
}

MyString.h: MyString.h:

#include <iostream>
using namespace std;

class MyString
{
private:
    int length;
    char* content;

public:

    friend ostream& operator << (ostream& out, const MyString& anotherString);

    MyString(); // Constructor fara parametrii
    MyString(int, const char*); // Constructor cu 2 parametrii
    MyString(const char*); // Constructor cu 1 parametru

    friend const MyString operator+(MyString&, MyString&);

    // setters and getters
    void setLength(int);
    const int getLength();
    void setContent(char*);
    const char* getContent();

    // destructor
    ~MyString();
};

Main.cpp: Main.cpp:

#include <iostream>
#include "MyString.h"
using namespace std;

int main() {

    MyString string1("---");
    MyString string2("..");

    cout << (string1 + string2);


    system("pause");
    return 1;
}

In

const MyString operator+(MyString& string1, MyString& string2)
{
    MyString concatString;
    concatString.setLength(string1.length + string2.length);
    strcat(string1.content, string2.content);
    concatString.setContent(string1.content);

    return concatString;
}

concatString is created empty, and setLength only set the length without (re)allocated content , so you strcpy a null pointer in setContent concatString创建空的,setLength只设置长度不(再)分配的内容 ,让你在strcpy的一个setContent空指针

you also need to copy and concat in concatString , not in string1 您还需要在concatString中而不是string1中复制并concat

So for instance : 因此,举例来说:

void MyString::setLength(int length) 
{
    if (length > this->length) {
      char * b = new char[length + 1];

      if (this->content != NULL) {
        strcpy(b, this->content);
        delete [] this->content;
      }
      this->content = b;
    }
    this->length = length;
}

const MyString operator+(const MyString& string1, const MyString& string2)
{
    MyString concatString;
    concatString.setLength(string1.length + string2.length);
    strcpy(concatString.content, string1.content);
    strcat(concatString.content, string2.content);

    return concatString;
}

setContent cannot just do a strcpy , better to do for instance setContent不能仅仅做一个strcpy ,例如做得更好

void MyString::setContent(char* content) 
{
  if (content == NULL) {
    if (this->content != NULL) 
      delete [] this->content;
    this->content = NULL;
    this->length = 0;
  }
  else {
    setLength(strlen(content));
    strcpy(this->content, content);
  }
}

After these two changes, compilation and execution : 在完成这两个变化,编译和执行:

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra -g MyString.cpp Main.cpp 
In file included from MyString.cpp:2:0:
MyString.h:22:25: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     const int getLength();
                         ^
MyString.cpp:41:31: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
 const int MyString::getLength()
                               ^
In file included from Main.cpp:2:0:
MyString.h:22:25: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     const int getLength();

pi@raspberrypi:/tmp $ ./a.out
Content:
---..
Length:
5
sh: 1: pause: not found

and under valgrind valgrind下

pi@raspberrypi:/tmp $ valgrind ./a.out
==6134== Memcheck, a memory error detector
==6134== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6134== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6134== Command: ./a.out
==6134== 
Content:
---..
Length:
5
sh: 1: pause: not found
==6134== 
==6134== HEAP SUMMARY:
==6134==     in use at exit: 0 bytes in 0 blocks
==6134==   total heap usage: 5 allocs, 5 frees, 21,261 bytes allocated
==6134== 
==6134== All heap blocks were freed -- no leaks are possible
==6134== 
==6134== For counts of detected and suppressed errors, rerun with: -v
==6134== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

To not have the warning during the compilation do not return const int but just int 要在编译期间没有警告,请不要返回const int,而只是返回int

It is better to have length to be a size_t rather than a int 最好使长度size_t而不是int

getLength and getContent can be const ( int getLength() const and const char* getContent() const ) 的getLength的getContent可以是常量int getLength() constconst char* getContent() const


As Christophe says in a remark operator+ returns a copy of the string and you do not define the copy constructor, nor the operator= . 作为克里斯托弗的言论说operator+返回字符串的副本,你没有定义拷贝构造函数,也不是operator= When a class contains pointers it is needed to define them, and with recent C++ also the move 当一个类包含指向它需要去界定,并与近期C ++还

There are a couple of problems with this code. 这段代码有两个问题。

First, you need to implement the rule of 3 , so also providing a copy constructor and an assignment operator. 首先,您需要实现3规则 ,因此还需要提供复制构造函数和赋值运算符。

Then setLength() adjust the maximum length of your string, but it fails to allocate anything, so that you may create a buffer overflow, or in case the default constructor was used an UB because of the nullptr. 然后setLength()调整字符串的最大长度,但是它无法分配任何内容,因此您可能会创建缓冲区溢出,或者由于nullptr而使用默认构造函数的情况下使用UB。 This is what happens in your operator+() . 这就是在operator+()发生的情况。

Once you have implemented the rule of 3, a quick fix for operator+ could be: 实施3规则后,对operator +的快速修复可能是:

const MyString operator+(MyString& string1, MyString& string2)
{
    MyString concatString(string1.length + string2.length, string1.content);
    strcat(concatString.content, string2.content);

    return concatString;   // but this requires copy constructor to work
}

You for your length-based constructor, you assule that length is larger than the string that you want to copy. 对于基于长度的构造函数,应确保该长度大于要复制的字符串。 So either you assert this, or you use strncpy() 因此,您可以断言这一点,或者使用strncpy()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Metrics_Alpha.exe 中 0x78F90870 (ucrtbased.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000000 - Unhandled exception at 0x78F90870 (ucrtbased.dll) in Metrics_Alpha.exe: 0xC0000005: Access violation reading location 0x00000000 CandidateVotes.exe中0x50E6F1C0(ucrtbased.dll)抛出异常:0xC0000005:访问冲突读取位置0x00000000 - Exception thrown at 0x50E6F1C0 (ucrtbased.dll) in CandidateVotes.exe: 0xC0000005: Access violation reading location 0x00000000 c++ 在 ConsoleApplication1.exe 中的 0x7A45FF80 (ucrtbased.dll) 处抛出异常:0xC0000005:访问冲突读取位置 0x00000000 - c++ Exception thrown at 0x7A45FF80 (ucrtbased.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation reading location 0x00000000 labs.exe中0x6BE20E11(ucrtbased.dll)的未处理异常:0xC0000005:访问冲突读取位置0x0000004D - Unhandled exception at 0x6BE20E11 (ucrtbased.dll) in labs.exe: 0xC0000005: Access violation reading location 0x0000004D 在0xC0000005中的0x6ececafa出现未处理的异常:访问冲突写入位置0x00000000 - Unhandled Exception as at 0x6ececafa in 0xC0000005 : Access violation writing location 0x00000000 在 ConsoleApplication5.exe 中的 0x0F640E09 (ucrtbased.dll) 处抛出异常:0xC0000005:访问冲突写入位置 0x014C3000? - Exception thrown at 0x0F640E09 (ucrtbased.dll) in ConsoleApplication5.exe: 0xC0000005: Access violation writing location 0x014C3000? HW 5 Rational pt2.exe 中 0x5E10F1C0 (ucrtbased.dll) 处未处理的异常:0xC0000005:访问冲突读取位置 0xCCCCCCCC。 发生了 - Unhandled exception at 0x5E10F1C0 (ucrtbased.dll) in HW 5 Rational pt2.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC. occurred NVIDIA未处理的异常,位于0x002a2da2中 <work.exe> 0xC0000005:访问冲突读取位置0x00000000 - NVIDIA Unhandled exception at 0x002a2da2 in <work.exe>0xC0000005: Access violation reading location 0x00000000 tester.exe中0x00b21840处未处理的异常:0xC0000005:访问冲突读取位置0x00000000 - Unhandled exception at 0x00b21840 in tester.exe: 0xC0000005: Access violation reading location 0x00000000 Project4.exe中0x00998876处的首次机会异常:0xC0000005:访问冲突写入位置0x00000000 - First-chance exception at 0x00998876 in Project4.exe: 0xC0000005: Access violation writing location 0x00000000
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM