присвоение выделенной кучи ссылки на выделенную переменную стека - PullRequest
1 голос
/ 12 декабря 2011

Возможно ли это? Судя по тому, что я пытаюсь сделать, это не так.

Функция

static std::string str_repeat(std::string * str, int num_times) {

    std::string * str_rep = new std::string;

    for (int n = 1; n <= num_times; n++) {
        str_rep = str_rep + str;
    }

    std::string ret = *str_rep; //error

    delete str;
    delete str_rep;

    return ret;
}

Обновление

Извините, я не публиковал сообщение об ошибке, потому что думал, что это универсальная проблема C ++, которую я делал неправильно. Вот оно.

error: invalid operands of types ‘std::string* {aka std::basic_string<char>*}’ and ‘std::string* {aka std::basic_string<char>*}’ to binary ‘operator+’

Ответы [ 4 ]

7 голосов
/ 12 декабря 2011

Прежде всего, если вы когда-нибудь скажете new std::string, вы, вероятно, делаете что-то не так.В этом коде не должно быть указателей (а str_rep = str_rep + str - это арифметика указателей в вашем коде, а не добавление, поэтому разыменование результата завершается неудачно).

std::string str_repeat(const std::string& str, int num_times) {
    std::string ret;
    for (int n = 0; n < num_times; ++n) {
        ret += str;
    }
    return ret;
}
1 голос
/ 12 декабря 2011

Вы пытаетесь добавить два указателя вместе, поэтому он не будет компилироваться. Не забывайте, что указатель является адресом памяти, оператор + не будет вызываться в вашем примере - вам придется разыменовать указатель, но я бы не рекомендовал этот шаблон в этом случае. Я бы посоветовал вам прочитать немного больше об указателях и ссылках: -)

Будьте очень осторожны при удалении памяти. Это плохая практика - удалять память вне контекста, в котором она была выделена - это рецепт ошибок. Кроме того, если вы разместите в стеке перед вызовом 'delete str', ваше приложение, скорее всего, аварийно завершит работу.

Для работы со строками я бы очень рекомендовал передавать по константной ссылке. Таким образом, он будет иметь дело с распределением памяти для вас, так как вы можете передать std :: string по значению, и он будет внутренне выполнять выделение памяти по мере необходимости ...

Еще пара моментов. В языках C мы обычно считаем «0», поэтому я бы изменил ваш цикл for В правильном приложении у меня есть некоторые отладочные утверждения для ваших входных параметров: то есть вы должны утверждать, что num_times равен '> 0'

Следующий код компилируется и выполняется с результатом "barbarbar" ...

Ура и удачи, Jon

#include <string>
#include <iostream>

using namespace std;

static string str_repeat(const string& str, int count)
{
    string returnData;

    for (int n = 0; n < count; n++)
    {
        returnData.append(str);
    }

    return returnData;
}

int main(int argc, char* argv[])
{
    string foo = "bar";

    string duplicated = str_repeat(foo, 3);

    cout << duplicated;

    return 0;
}
1 голос
/ 12 декабря 2011

operator + на std::string * означает манипулирование указателем, не конкатенация строк. Вам не нужно прыгать через любой из этих обручей, хотя; std::string будет внутренне выделять буфер, достаточно большой для его содержимого. Измените свою функцию на это:

static std::string str_repeat(const std::string& str, int num_times) {
    std::string result("");

    for (int n = 1; n <= num_times; n++) {
        result += str;
    }

    return result;
}

И вызывать его, передавая правильную строку, а не адрес строки:

std::string myString(...);
std::string str = str_repeat(myString, 10);
std::string str2 = str_repeat("foobar", 100);

Я чувствую, что для этой цели уже есть стандартная библиотечная функция, хотя я не могу думать об этом случайно.

1 голос
/ 12 декабря 2011

Я предполагаю здесь, потому что это то, что вы просили.Когда вы решите рассказать миру, что именно означает «ошибка», мне, возможно, придется пересмотреть ответ.

Я предполагаю, что у вас ошибка во время выполнения, потому что *str_rep является мусором.

Это мусор из-за этой части:

for (int n = 1; n <= num_times; n++) {
    str_rep = str_rep + str;
}

Оба str_rep и str являются указателями, и вы добавляете один к другому, но на что они указывают?Если вы хотите добавить строки, выполните:

for (int n = 1; n <= num_times; n++) {
    *str_rep = *str_rep + *str;
}

Или просто не используйте указатели вообще, не вижу никакой выгоды в этом.

...