我在代码的特定部分遇到异常

Posted

技术标签:

【中文标题】我在代码的特定部分遇到异常【英文标题】:I'm getting an exception in particular part of code 【发布时间】:2019-09-06 17:06:12 【问题描述】:

我在编译重载运算符时遇到指针异常。异常显示“抛出异常:写访问冲突。 TempString.Pointer 是 0x1110112。”我希望操作员将两个自定义字符串合二为一。

重载运算符:

MyString MyString::operator+(MyString &String) 
    MyString TempString;
    TempString.StringLength = this->StringLength + String.StringLength;
for (int i = 0; i < this->StringLength + String.StringLength - 1; i++) 
    if (i < this->StringLength) 
        TempString.Pointer[i] = this->Pointer[i]; // Exception pops up here
    
    else 
        TempString.Pointer[i] = String.Pointer[i];
    

return TempString;
;

构造函数:

MyString::MyString() 
    StringLength = 0;
    Pointer = nullptr;


MyString::MyString(char* String) 
    Pointer = String;
    for (int i = 0; Pointer[i]; i++) 
        StringLength++;
    

Main.cpp:

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

int main() 

    char String1[] = "abcdef";
    MyString NewString(String1);

    char String2[] = "cdefa";
    MyString SubString(String2);

    MyString BrandNewString(NewString + SubString);
    cout << BrandNewString.GetStringLength() << endl;
    system("pause");
    return 0;

【问题讨论】:

Pointer = String; 非常非常非常危险。当您“空”它(或其类死亡)时,如果相同的指针存储在其他类中,它将变得无效。请改用std::shared_ptr。 您没有处理分配和解除分配。您对指针所有权有疑问。封装对于使这些成为可能很重要。 请显示minimal reproducible example 这看起来也不像 operator+ 的正常签名。对于你的水平,你有太多的概念在起作用。您应该遵循教科书。 【参考方案1】:

行:

TempString.StringLength = this->StringLength + String.StringLength;

不为您的字符串分配内存。 您需要在写入之前分配内存(在TempString.Pointer[i] = this-&gt;Pointer[i] 行)。

你能展示你的构造函数内容吗?

你写的是一个只读的字符串类。它附加到外部字符数组。

这很不幸,但你不能改变它们。请注意,您可以修改外部 char 数组的内容,但不能修改大小。 要进行连接(如在abc+def 中),您需要创建一个与两个初始数组的长度之和一样大的数组,但您的代码中没有这样的数组。

所以你需要先创建它们(它被称为分配,通常使用operator new,也可以使用malloc),但是你的类将无法知道它指向的数组是否由本身或来自其他任何地方。因此,您的班级将无法释放数组。

因此,您应该选择您希望班级执行的场景:

    保持只读类(您将无法执行串联或任何改变数组大小的操作)。 成为一个真正的字符串类(您必须在构造函数中分配一个字符数组并在析构函数中释放它),然后将接收到的字符串复制到您自己的托管数组中。虽然您将编写这样一个类,但您应该看看 std::string 类,它现在正在这样做。

你应该有什么,逻辑上在一个连接运算符中:

MyString MyString::operator+(const MyString & o) const 
   MyString ret(length + o.length);
   for(int i = 0; i < length; i++)
       ret.pointer[i] = pointer[i];
   for(int i = 0; i < o.length; i++)
       ret.pointer[i+length] = o.pointer[i];
   return ret;


MyString::MyString(int length) 
: length(length), pointer(new char[length+1]) 

  pointer[length] = 0;


MyString::~MyString()  delete[] pointer; pointer = nullptr; length = 0; 

MyString::MyString(const char * str)
: length(strlen(str)), pointer(new char[length+1])

    memcpy(pointer, str, length+1);

【讨论】:

上面显示了两个构造函数。还是我弄错了?

以上是关于我在代码的特定部分遇到异常的主要内容,如果未能解决你的问题,请参考以下文章

关于我在代码中遇到的异常,我需要解决方案

计算数据框特定领域内的异常值? [复杂的]

沙盒 AppDomain 跨程序集异常处理

我不知道如何循环我的代码的特定部分

如何捕获 Firebase Auth 特定异常

检查 PL/SQL 异常块中的特定错误代码