Создание массива символов с `new` генерирует больше символов, чем я указываю.C ++ - PullRequest
0 голосов
/ 21 января 2019

Итак, у меня есть задание для моего класса CS, которое доставляет мне некоторые проблемы.Цель состоит в том, чтобы создать свой собственный класс String, не заканчивающийся NULL, без использования каких-либо функций cstring.Данные в классе должны содержать длину строки, char*, называемую «данными», и некоторые другие вещи, не связанные с моим вопросом.

Поэтому, когда я иду, чтобы выделить память дляВ строке, я вызываю функцию MyStrCopy(MyString* tar, const char* str), которая использует tar->data = new char[length] для выделения памяти, "length" - это длина строки cstring, переданной как str, которая работает как задумано.Однако при распределении памяти таким способом массив всегда намного больше, чем я указал (например, я прошу 6 байтов и получаю больше 11), а число получаемых байтов кажется случайным, и оно отличается за цикл.Я попытался написать функцию для отбраковки нежелательных символов, но мне кажется, что мне просто не хватает навыков / знаний, как бы я этого достиг.

Эти дополнительные данные отбросили пару моих функций, и яЯ застрял в том, как это исправить.Любые идеи?

Я определил мой класс ниже

#include <iostream>
#pragma once

class MyString {
private:
    char* data;
    int length;
    static bool printAsUppercase;

    int getLengnth(const char* str);
    void MyStrCopy(MyString* tar, const char* str);

public:
// Constructors
    MyString();
    MyString(const char* data);
    MyString(MyString& data2Copy);
    ~MyString();

// Operator Overloads
    // Assignment Operator
    MyString operator=(const MyString& data);
    MyString operator=(const char* data);
    // Arithmetic Operators 
    MyString operator+(const MyString& rightStr);
    // Pre/Post decrement
    MyString operator--();
    MyString operator--(int);
    // Boolean Operators
    friend bool operator==(const MyString& leftStr, const MyString& rightStr);
    friend bool operator>(const MyString& leftStr, const MyString& rightStr);
    friend bool operator<(const MyString& leftStr, const MyString& rightStr);
    // Streaming Operators
    friend std::ostream& operator<<(std::ostream& os, const MyString& str);
    friend std::istream& operator>>(std::ostream& is, MyString& str);
// Mutators
    MyString& uppercase();
    void cull();
// Accessors
    int getLengnth();
};

и вот реализация.Примечание: большая часть этого в настоящее время не работает должным образом.

#include "MyString.h"

// Constructors
MyString::MyString() {
    data = NULL;
    length = 0;
}

MyString::MyString(const char* data) {
    MyStrCopy(this, data);
}

MyString::MyString(MyString& data2Copy) {
    MyStrCopy(this, data2Copy.data);
}

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

MyString MyString::operator=(const MyString& data) {
    MyString temp;
    MyStrCopy(&temp, data.data);
    return temp;
}

MyString MyString::operator=(const char* data) {
    MyString temp;
    MyStrCopy(&temp, data);
    return temp;
}

void MyString::MyStrCopy(MyString* tar, const char* str) {
    // WIP Something's not right with the NEW line
    tar->length = getLengnth(str);
    if (data != NULL)
        delete data;
    tar->data = new char[length];
    for (int i = 0; i < tar->length; i++)
        tar->data[i] = str[i];
    tar->cull();
}

void MyString::cull() {
    // WIP currently does effectively nothing
    int currLen = getLengnth(data);
    while (currLen > length)
        data[currLen--];
}

int MyString::getLengnth() {
    return length;
}

int MyString::getLengnth(const char* str) {
    int len = 0;
    while (str[len] != NULL)
        len++;
    return len;
}

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 21 января 2019
MyString::MyString(MyString& data2Copy) {
  MyStrCopy(this, data2Copy.data);
}

Это, по сути, конструкция по умолчанию для нового экземпляра MyString без инициализации какого-либо из его членов перед вызовом MyStrCopy()MyStrCopy:

if (data != NULL)
    delete data;

Поскольку ни data, ни какие-либо другие члены нового класса не были инициализированы - по причинам, указанным выше, data здесь будет случайным мусором ис этого момента все это неопределенное поведение.

0 голосов
/ 12 февраля 2019

Итак, как оказалось, дополнительные символы, которые я получал в отладчике, были отладчиком, который пытался помочь, продолжая печатать символы, пока не нашел NULL, что могло быть где угодно, так как мне не разрешили завершить Null,Я думал, что на самом деле что-то не так с моим компьютером, но нет, это просто отладчик.Спасибо за все дополнительные комментарии по этому вопросу;это действительно помогло мне разобраться!

0 голосов
/ 21 января 2019

Вы хотите сделать:

new char[tar->length];

Свойство length не инициализировано, поэтому вы получаете неопределенное поведение, хотя я наверняка зашагал бы в отладчике.Это некоторый запутанный код, поскольку MyStrCopy не является функцией static, вам не нужно вызывать ее с явным аргументом tar, который подразумевается как this.

.больше смысла вызывать эту функцию copy(const char* data) вместо вводящего в заблуждение стиля имени класса MyStrCopy.Пройдите только то, что вам нужно, например, data, и работайте со свойствами напрямую, а не косвенно через аргументы.

Помните, что вы можете определить конструктор в терминах другого конструктора:

MyString(const char* data);
MyString(const MyString& src) : MyString(src.data) { };

Там, где функция copy полностью исчезает, поскольку она является частью первого конструктора.

Здесь также есть некоторые опечатки, такие как getLengnth, поэтому обязательно перепроверьте все.

...