基本实现,但会在内存分配上翻车

main
lensfrex 2 years ago
parent 81c9d3cfe5
commit 8b59d554df
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 4
      work20220401/main.cpp
  2. 296
      work20220401/neoString/CString.cpp
  3. 8
      work20220401/neoString/CString.h

@ -1,9 +1,13 @@
#include <cstring>
#include "iostream" #include "iostream"
#include "neoString/CString.h" #include "neoString/CString.h"
using namespace std; using namespace std;
int main() { int main() {
// char *p = new char[15]();
// strncpy(p, "asdf", 4);
// cout << p;
int n, i, j; int n, i, j;
while (cin >> n) { while (cin >> n) {
CString *c = new CString[n + 2]; CString *c = new CString[n + 2];

@ -1,125 +1,171 @@
// //
// Created by lenfrex on 2022/4/4. // Created by lenfrex on 2022/4/4.
// //
#include <cstring> #include <cstring>
#include <algorithm> #include <algorithm>
#include "CString.h" #include "CString.h"
/* /*
* *
*/ */
CString::CString(int length) { CString::CString(int length) {
data = new char[length](); data = new char[length]();
CString::length = length; }
}
CString::~CString() {
CString::~CString() { delete[] data;
delete[] data; data = nullptr;
} }
/* /*
* 512 * 512
*/ */
CString::CString() : CString(512) {} CString::CString() : CString(512) {}
/* /*
* Java中String类的equal() * Java中String类的equal()
* falsedata为nullptrfalse * data是否为nullptrnull则truefalse
* true * false
* * true
*/ *
bool CString::operator==(const CString &source) const { */
// 判断两CString长度以及本对象data成员是否为空指针 bool CString::operator==(const CString &source) const {
if (source.length != length || data == nullptr) { // 首先判断两CString对象data成员是否为空指针
return false; if (source.data == nullptr || this->data == nullptr) {
} else { return source.data == nullptr && this->data == nullptr;
// 判断两对象data成员是否指向同一内存块 }
if (source.data == data) {
return true; int length = (int)strlen(data);
} int sourceLength = (int)strlen(source.data);
}
// 字符串长度不等,字符串肯定是不等
// 以上情况都不符合时才进行逐字比较 if (length != sourceLength) {
int compareLength = std::min(source.length, length); return false;
for (int i = 0; i < compareLength; ++i) { } else {
if (data[i] != source.data[i]) { // 长度相等且data指向相同肯定等
return false; if (source.data == this->data) {
} return true;
} }
return true; }
}
// 以上情况都不符合时才进行逐字比较
/* int compareLength = std::min(sourceLength, length);
* for (int i = 0; i < compareLength; ++i) {
*/ if (data[i] != source.data[i]) {
CString::CString(char *source) : CString((int)strlen(source)) { return false;
strncpy(data, source, length); }
} }
return true;
/* }
*
*/ /*
CString::CString(char *source, int length) : CString(length) { *
strncpy(data, source, length); */
} CString::CString(char *source) : CString((int)strlen(source)) {
strcpy(data, source);
CString &CString::operator=(const CString &source) { }
// 处理自己给自己赋值的情况,那叫啥,自赋值
if (this == &source) { /*
return *this; *
} */
CString::CString(char *source, int length) : CString(length) {
if (data != nullptr && length != 0) { strncpy(data, source, length);
delete[] data; }
}
CString &CString::operator=(const CString &source) {
this->length = source.length; // 处理自己给自己赋值的情况,那叫啥,自赋值
this->data = new char[length](); if (this == &source) {
return *this;
strncpy(data, source.data, length); }
return *this; delete[] data;
}
// 等号右侧空指针的话直接data赋为空指针
CString &CString::operator+=(const CString &source) { // 这里在执行前就已经delete掉data的数据了,不会泄漏
if (data == nullptr && length == 0) { if (source.data == nullptr) {
this->length = source.length; this->data = nullptr;
this->data = new char[length](); return *this;
} }
char *tmp = new char[length](); int sourceLength = (int)strlen(source.data);
strncpy(tmp, data, length);
this->data = new char[sourceLength]();
// 重新分配内存,防止拼接后溢出 strcpy(data, source.data);
delete[] data;
this->length += source.length; return *this;
this->data = new char[this->length]; }
strcpy(tmp, data); CString &CString::operator+=(const CString &source) {
strncat(data, source.data, source.length); // nullptr不做处理
if(source.data == nullptr) {
return *this; return *this;
} }
CString::CString(const CString &source) : CString(source.data, source.length) {} int sourceLength = (int)strlen(source.data);
int length = 0;
/*
* // 本对象nullptr的话就直接新分配
*/ if (data == nullptr) {
bool CString::operator<(const CString &source) const { this->data = new char[sourceLength]();
// 这部分类似于前边==重载的前置判断,如果本对象数据为null或者两对象数据是一回事就直接false length = sourceLength;
if (data == nullptr || (source.length != length && source.data == data)) { } else {
return false; length = (int)strlen(data);
} }
// 以上情况都不符合时才进行逐字比较 // 保存拼接前的原数据,以便重新分配足够的内存
int compareLength = std::min(source.length, length); char *old = new char[length]();
for (int i = 0; i < compareLength; ++i) { strcpy(old, data);
if (data[i] < source.data[i]) {
return true; // 重新分配内存,防止拼接后溢出
} length += sourceLength;
} delete[] data;
return false; this->data = new char[length]();
}
strcpy(data, old);
strcat(data, "--");
strncat(data, source.data, sourceLength);
return *this;
}
CString::CString(const CString &source) : CString(source.data) {}
/*
*
*/
bool CString::operator>(const CString &source) const {
// 首先判断两CString对象data成员是否为空指针,空直接返回false
if (source.data == nullptr || this->data == nullptr) {
std::cout << "nullptr!"<< std::endl;
return false;
}
int length = (int)strlen(data);
int sourceLength = (int)strlen(source.data);
// 两对象指向data同一内存区域并且长度相等则可以判断两字符串相等,所以就不是"<"
if (sourceLength == length && source.data == this->data) {
std::cout << "memsame" << std::endl;
return false;
}
// 以上情况都不符合时才进行逐字比较
int compareLength = std::min(sourceLength, length);
for (int i = 0; i < compareLength; ++i) {
if (data[i] > source.data[i]) {
std::cout << "data[i]: " << data[i] << " source.data[i]: " << source.data[i] << std::endl;
return true;
}
}
return false;
}
std::ostream &operator<<(std::ostream &outputStream, const CString &source) {
return outputStream << source.data;
}
std::istream &operator>>(std::istream &inputStream, const CString &source) {
return inputStream >> source.data;
}

@ -5,13 +5,13 @@
#ifndef WORK20220401_CSTRING_H #ifndef WORK20220401_CSTRING_H
#define WORK20220401_CSTRING_H #define WORK20220401_CSTRING_H
#include <iostream>
#include "utility" #include "utility"
using namespace std::rel_ops; using namespace std::rel_ops;
class CString { class CString {
private: private:
char *data = nullptr; char *data = nullptr;
int length = 0;
public: public:
explicit CString(int length); explicit CString(int length);
@ -27,12 +27,14 @@ public:
bool operator==(const CString &source) const; bool operator==(const CString &source) const;
bool operator<(const CString &source) const; bool operator>(const CString &source) const;
CString &operator+=(const CString &source); CString &operator+=(const CString &source);
CString &operator=(const CString &source); CString &operator=(const CString &source);
};
friend std::ostream &operator<<(std::ostream &outputStream, const CString &source);
friend std::istream &operator>>(std::istream &outputStream, const CString &source);
};
#endif //WORK20220401_CSTRING_H #endif //WORK20220401_CSTRING_H

Loading…
Cancel
Save