如何使用C++初始化堆内存中的常量数组?

8yparm6h  于 2023-02-10  发布在  其他
关注(0)|答案(5)|浏览(187)

在C++中,我们可以为动态数组分配堆内存,但是如果它是一个只读数组,我们如何初始化它呢?

const char* str = new char[3];

在运行这个语句后,系统似乎用垃圾值隐式初始化变量str,这意味着我不能改变它的值,因为它有一个常量限定符。那么我如何在堆内存中创建一个常量字符串并显式初始化它呢?
如果我想在堆内存中创建一个对象,我需要一个指向该对象的指针。但是如果它是常量,我甚至不能在它在堆内存中创建之后用指针改变它。所以这对我来说成了一个恶性循环。

pgx2nnw8

pgx2nnw81#

您可以从char *开始修改数组,然后将其转换为const char *

char *str = new char[3];
// str[i] = ...
const char *cstr = str;

但是,除非您尝试实践动态内存管理,否则这些都不是必须的,只需要使用std::stringstd::vector<char>即可。

r7knjye2

r7knjye22#

运算符new调用不会分配const内存,当你把它赋值给变量时,它会被转换成const,解决方法是创建一个非常量的临时变量,把数据写入其中,最后把它转换成常量指针:

#include <cstring>
#include <memory>

std::unique_ptr<const char[]> PutBytesOntoHeap(const char* data, size_t size)
{
    std::unique_ptr<char[]> result(new char[size]);
    memcpy(result.get(), data, size);
    return result;
}
olqngx59

olqngx593#

在当前的c中,避免显式调用new/delete,只在数据结构内部使用它(即使这样,std::make_unique也是首选)。所以使用std::vector(或者std::string/std::string_view)
@273K还请注意大多数C
书籍(教师,在线材料)都过时了。

#include <vector>

int main()
{
    std::vector<char> str{ 'a', 'b', 'c' }; // this will do the memory allocation for you

    // for local use (when a legacy api needs a pointer, otherwise don't use)
    const char* ptr = str.data();

    return 0;

    // std::vector goes out of scope
    // will free the allocated memory (so you can't forget to call delete[])
}
czfnxgou

czfnxgou4#

如果它是常量,我甚至不能在堆内存中创建它之后用指针改变它

const char* str = new char[3];

你实际上创建了一个非constchar数组,并将其赋值给const char*,你也可以将其赋值给char*,进行你想要的修改,然后返回一个const char*,例如:

auto str = []() -> const char* {
    char* rv = new char[3];
    rv[0] = '1';
    rv[1] = '2';
    rv[2] = '\0';
    return rv;
}();

如何在堆内存中创建常量字符串并显式初始化它?
可以使用new const char[]和初始化器:

auto str = new const char[3]{'1', '2', '\0'};

helper函数可能如下所示:

#include <cstddef>
#include <iostream>
#include <utility>

template <std::size_t N>
auto make_const_cstring(const char (&s)[N]) {
    return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
        return new const char[N]{s[Is]...};
    }(std::make_index_sequence<N>());
}

int main() {
    auto str = make_const_cstring("Hello world");
    std::cout << str << '\n';
    delete[] str;
}
tp5buhyn

tp5buhyn5#

如果你想在创建数组的函数返回后使用它,那么在堆中而不是在运行时堆栈中分配该数组。表达式new T[size]分配一个新数组,其中包含大小变量,每个变量的类型为T。记住,数组被当作指向数组中第一个元素的指针来处理。因此表达式new int[25]的类型为int*。语句
整数 * A =新整数[25];
分配一个新的25个整型数组,并将指向第一个整型数组的指针存储到变量A中。
大小可以由任何生成整数的表达式给定。例如,如果您已经有一个名为n的整数变量,当前值为50,则
双精度 * B =新双精度[n];
分配一个包含50个双精度值的数组。

相关问题