Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
unylkun
0 / 0 / 0
Регистрация: 31.12.2016
Сообщений: 8
#1

Работа с памятью - C++

02.02.2017, 20:09. Просмотров 210. Ответов 3
Метки нет (Все метки)

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

Суть такова: написал class String, в нем реализовал метод превращения двух строк в одну. Попутно ради практики использовал указатель this, и вроде понял, для чего он нужен - для того, чтобы компилятор не путал аргументы, передаваемые в метод и то, что находится в полях класса (поправьте, если ошибаюсь). Непосредственно вопрос: У меня в коде 2 раза выделяется память, освобождается же 1, в деструкторе прописана команда. Так и должно быть, или это не норма? Если норма - прошу объяснить почему. Так же буду крайне признателен за конструктивную критику кода и самой реализации.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <cstring>
using namespace std;
 
 
class String
{
    private:
        char *str;
        int size;
    public:
        String();
        String(char *str);
        char* append(char *str); //Метод, объединяющий две строки в одну
        ~String();
};
 
String::String()
{
    str = NULL;
    size = 0;
    //cout << "Сработал конструктор по умолчанию." << endl;
}
 
String::String(char *str)
{
    size = strlen(str);
    this->str = new char[size]; //Выделяем память
    for(int i(0); i < size; i++)
    {
        this->str[i] = str[i];
    }
    //cout << "Сработал конструктор с параметром." << endl;
}
 
char* String::append(char *str)
{
    char *buff = new char[size];
    for(int i(0); i < size; i++)
    {
        buff[i] = this->str[i];
    }
    
    int n = size;
    size = size + strlen(str);
    this->str = new char[size]; //Выделяем память второй раз
    
    for(int i(0); i < n; i++)
    {
        this->str[i] = buff[i];
    }
    
    for(int i(0); i < size; i++)
    {
        this->str[i + n] = str[i];
    }
    
    delete []buff;
 
    return this->str;
}
 
String::~String()
{
    delete []str;   //освобождаем
    //cout << "Сработал деструктор" << endl;
}
 
int main()
{
    
    setlocale(LC_ALL,"rus");
    String str_1("Hello, ");
    cout << str_1.append("World!");
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.02.2017, 20:09
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Работа с памятью (C++):

Работа с памятью - C++
Всем доброго времени суток. Почитав данный форум и проч. пришёл к выводу, что мой проект на C# нереален в виду бестолковой работы с...

Работа с памятью - C++
Есть приложение,в нем есть label'ы. Есть ли какая-нибудь возможность средствами C++ допустим, перевести эти контролы? Если есть - дайте...

работа с памятью - C++
Доброго времени суток! У меня возникло затруднение - нужно реализовать на языке Си программу,демонстрирующую распределение памяти таким...

Работа с памятью - C++
Добрый день всем. Я только начал изучение C#(раньше работал c: C++ маленько -т.е. общее представление о нем имею) и у меня вопрос, можно...

Работа с памятью - C++
Может кто хорошо понимает механизм выделения и освобождения памяти объяснить его, а то я в конец запутался с ним, вот помогал одному...

Работа с памятью - C++
Всем привет! Не могу разобраться, как написать код программы, которая моделирует механизм виртуальной памяти. Кто сможет реализовать хотя...

3
likehood
offline
888 / 747 / 253
Регистрация: 25.12.2016
Сообщений: 2,474
Завершенные тесты: 3
02.02.2017, 21:24 #2
Цитата Сообщение от unylkun Посмотреть сообщение
У меня в коде 2 раза выделяется память, освобождается же 1, в деструкторе прописана команда.
Я вижу два вызова delete: в 58 и 65 строках.
Цитата Сообщение от unylkun Посмотреть сообщение
Так же буду крайне признателен за конструктивную критику кода и самой реализации.
На сколько я вижу, в конце строки не хранится нулевой байт. А значит, выдавать такую строку во внешний мир бессмысленно/небезопасно. В частности, в 74 строке кроме "Hello, world!" будет напечатан какой-то мусор.
Поэтому лучше потратить лишний байт и записать в него признак конца строки.
1
unylkun
0 / 0 / 0
Регистрация: 31.12.2016
Сообщений: 8
02.02.2017, 23:40  [ТС] #3
Значит я не совсем правильно выразился, память выделяется еще в 38 строке, получается 3 раза. Я просто не акцентировал на этом внимание, т.к освобождается она сразу в этом методе. Интересует переменная str, для неё я выделил память в 28 и 46 строках. Потом она освобождается в деструкторе один раз. Это норма?))

За замечание спасибо.

UPD: Нулевой байт нужно добавить в вызов метода .append в 74 строке? (Присобачить его к World?) К слову, когда компилировал код, выводилась только строка, никакого мусора
0
likehood
offline
888 / 747 / 253
Регистрация: 25.12.2016
Сообщений: 2,474
Завершенные тесты: 3
03.02.2017, 11:27 #4
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от unylkun Посмотреть сообщение
память выделяется еще в 38 строке, получается 3 раза
Действительно, что-то я не заметил в первый раз, невнимательно смотрел.
Теперь заметил, что в 46 строке будет утечка памяти: мы меняем указатель this->str, не удалив память, на которую он указывал.

Цитата Сообщение от unylkun Посмотреть сообщение
выводилась только строка, никакого мусора
Тут уж как повезёт. Если в конце программы добавить строку cout << str_1.append(" Another string.");, то у меня программа вообще падает.

Привожу свою реализацию, не меняющую интерфейс класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cstring>
 
using namespace std;
 
class String
{
private:
    char *str;
    size_t size;
 
public:
    String();
    String(char *s);
    char* append(char *s); //Метод, объединяющий две строки в одну
    ~String();
};
 
String::String() : str(nullptr), size(0)
{
}
 
String::String(char *s)
{
    size = strlen(s);
    str = new char[size+1]; //Выделяем память
    // копируем s -> str, включая нулевой байт
    memcpy(str, s, size+1);
}
 
char* String::append(char *s)
{
    size_t n1 = size, n2 = strlen(s);
    char *newStr = new char[n1+n2+1];
 
    memcpy(newStr, str, n1);
    memcpy(newStr+n1, s, n2+1);
    size = n1+n2;
 
    delete[] str;
    return str = newStr;
}
 
String::~String()
{
    delete[] str;   //освобождаем
}
 
int main()
{
    setlocale(LC_ALL,"rus");
    String str_1("Hello, ");
    cout << str_1.append("World!") << endl;
    cout << str_1.append(" Another string.") << endl;
}
0
03.02.2017, 11:27
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.02.2017, 11:27
Привет! Вот еще темы с ответами:

Работа с памятью - C++
Нужно ривести пример использования операторов new и delete для выделения памяти под двумерный массив и освобождения памяти двумерного...

работа с памятью - C++
a) Статическая память. Двумерный массив. Дан массив целых чисел. В массиве есть отрицательные числа. Определить координаты левого нижнего...

Работа с памятью в С++ - C++
Здравствуйте. Если я правильно понимаю, то при запуске программы, программе выделяется определенное кол-во памями, которое оно может...

Работа с динамической памятью - C++
Привет всем. Я недавно начал изучать C++ и наткнулся на ошибку:&quot;двумерный динам.exe вызвал срабатывание точки останова&quot; при очистке...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.