1 Востаннє редагувалося pika1989 (16.10.2015 17:34:55)

Тема: Програма видає абрукадабру у visual studio

Задача: Написати функцію SubStr(const char * str, int pos, int len), яка повертає фрагмент  рядка,
починаючи з вказаної позиції(pos) та вказаної довжини(len). Рядок повертати як динамічний.
Реалізувала так :

Прихований текст

#include<iostream>
#include<cstring>

using namespace std;

char *SubStr(const char * str, int pos, int len)
{
    char *new_str = new char[len];
    if (pos >= 0 && pos < strlen(str) && (strlen(str) - len) > 0)
    {
        for (int i = pos, j = 0; i < len; ++i, ++j)
            *(new_str + j) = *(str + i);
    }
    return new_str;
}

int main()
{
    const int STRING_SIZE = 256;
    char text[STRING_SIZE] = "\0";
    char *new_text = NULL;

    cout << "Enter the text. Input complete the point\n";
    cin.getline(text, STRING_SIZE, '.');
    cin.ignore(STRING_SIZE, '\n');

    int new_length;
    cout << "Enter the length for new string: ";
    cin >> new_length;

    int new_pos;
    cout << "Enter the position that start copy to new string: ";
    cin >> new_pos;

    new_text = SubStr(text, new_pos, new_length);

    cout << "Your text:\n";
    cout << "\t" << text << "\n";

    cout << "New text:\n";
    cout << "\t" << new_text << "\n";

    return 0;
}

І ніби працює, але є одне "але": в результаті виконання вона видає мені таке (писала програму і компілювала у Visual Studio)

Прихований текст
http://i.imgur.com/gDEc9wf.png

Також компілювала програму за допомогою g++ - працює так, як потрібно. В чому може бути проблема?

2 Востаннє редагувалося Yola (16.10.2015 17:29:43)

Re: Програма видає абрукадабру у visual studio

Можливо g++ ініціалізує виділену пам"ять нулями. Покладіть у new_str 0 після останнього символу. І знов у вас витік пам'яті.

Подумайте про використання unique_ptr

ukrainian.stackexchange.com - це питання-відповіді з української мови

3

Re: Програма видає абрукадабру у visual studio

Yola написав:

Можливо g++ ініціалізує виділену пам"ять нулями. Покладіть у new_str 0 після останнього символу. І знов у вас витік пам'яті.

Чому? Тому що нема delete?

Yola написав:

Подумайте про використання unique_ptr

На жаль, ми його ще не вивчали.

4 Востаннє редагувалося koala (16.10.2015 18:17:50)

Re: Програма видає абрукадабру у visual studio

Вам треба

char *new_str = new char[len+1];//+1 для \0 в кінці

ну і цей самий \0 додати треба.

*(new_str + j) = *(str + i);

значно легше зрозуміти в формі

new_str[j] = str[i];

В циклі не треба дві змінні, вони лінійно залежні очевидним чином. Класичний цикл виглядатиме так:
char *source = &str[pos], *end = &str[pos+len], *dest = new_str;
while( source != end ) {
  *dest++ = *source++;
}

Що ж стосується безпечних вказівників, то, мені здається, тут, як і з goto, треба один-два рази добряче вляпатися, щоб зрозуміти, нащо вони потрібні.

Подякували: Yola, pika19892

5 Востаннє редагувалося Yola (17.10.2015 08:16:09)

Re: Програма видає абрукадабру у visual studio

pika1989 написав:

Чому? Тому що нема delete?

Так.

pika1989 написав:

На жаль, ми його ще не вивчали.

На майбутнє, приблизно так:

unique_ptr<char[]> SubStr(const char * str, int pos, int len)
{
    auto new_str = make_unique<char[]>(len+1);

    if (pos >= 0 && pos < strlen(str) && (strlen(str) - len) > 0)
    {
        for (int i = pos, j = 0; i < len; ++i, ++j)
            new_str[j] = *(str + i);
    }
    new_str[len] = 0;
    return new_str;
}

...
unique_ptr<char[]> new_text = SubStr(text, new_pos, new_length);

Виправив код. Однією з причин введення make_unique є бажання повністю виключити оператор new з коду програм. Зараз правильно.

ukrainian.stackexchange.com - це питання-відповіді з української мови
Подякували: pika19891