将堆分配的引用分配给堆栈分配的变量

assigning a heap allocated reference to a stack allocated variable

本文关键字:分配 堆栈 变量 引用      更新时间:2023-10-16

这可能吗?根据我正在努力完成的任务,情况似乎并非如此。

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+’

首先,如果你说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;
}

你试图将两个指针加在一起,这就是为什么它不会编译。不要忘记指针是一个内存地址,在你的例子中不会调用+操作符——你必须取消对指针的引用,但我不建议在这种情况下使用这种模式。我建议你多读一点关于指针和引用的知识:-)

删除内存时要非常小心。从分配内存的上下文中删除内存是一种不好的做法——这是导致bug的原因。此外,如果你在调用'delete str'之前在堆栈上进行了分配,你的应用程序可能会崩溃。

对于字符串操作,我建议通过const引用传递。因此,will将为您处理内存分配,因为您可以按值传递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;
}

我猜是因为这是你要求的。当你决定告诉全世界"错误"的确切含义时,我可能需要修改答案。

我猜你有一个运行时错误,因为*str_rep是垃圾。

是垃圾,因为这部分:

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

str_repstr都是指针,你把一个加到另一个上,但是它们指向什么?如果要添加字符串,请执行:

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

或者干脆不使用指针,这样做没有任何好处。

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);

我觉得已经有一个标准的库函数来实现这个目的了,尽管我一时想不起来。