GCC C++堆栈上的字符串



我正在运行一个带有c ++的嵌入式设备(是的,我将动态分配保持在绝对最小值(。但我想知道:

在 C 语言中

void Do_Something(const char* const pString);
void f()
{
Do_Something("some string");
}

pString实际上是一个位于任务堆栈上的数组。

在C++

void Do_Something(const string my_string);
void f()
{
Do_Something("some string");
}

我假设只有指向字符串my_string指针位于堆栈上。实际内容位于堆上,对吗?

第一个问题是否无论如何将字符串放在堆栈上(不使用char *(?

所有 STL 类(如字符串(在内部调用 new 以在堆上分配内存。现在,new 在失败时会引发异常。所以为了安全起见,我必须做这样的事情。

try
{
Do_Something("some string");
}
catch(const exception& ex)
{
//Exception handling
}

如果字符串在堆上,我必须对所有调用Do_something()执行此操作。有没有更好的方法?

编辑:感谢您所有非常有用的答案。这让我对接下来的日子有一些思考:)

如果可用,最好std::string_view

如果没有,则可以使用以类型安全方式接受字符串文本的版本重载Do_Something

class Do_Something_For_Real {
template <size_t N> friend void Do_Something(const char (&)[N]);
void operator () (const char * const pString, size_t N) {
//...
}
};
template <size_t N>
void Do_Something(const char (&pString)[N]) {
Do_Something_For_Real()(pString, N);
}

如果您必须具有与std::string具有相同语义的内容,则可以使用自定义分配器实例化std::basic_string,该分配器在询问时返回"堆栈"分配的内存。

template <size_t N>
struct fake_allocator {
char mem_[N];
void * allocate (size_t, const void * = 0) { return mem_; }
...
};

C 语言中的代码示例

void Do_Something(const char* const pString);
void f()
{
Do_Something("some string");
}

将常量指针添加到堆栈上的常量 char(更准确地说,在函数 Do_Something 的堆栈帧中(。以这种方式调用它时,将恰好将这种指针传递给位于程序数据区域中的字符串。因此,当谈论嵌入式系统时,它被放置在二进制文件的 .data 区域中(这在某些编译器之间可能会有所不同(。

您的C++代码

void Do_Something(const string my_string);
void f()
{
Do_Something("some string");
}

使用按值调用,即在堆栈上动态创建字符串对象的副本,这进一步可能会在堆上分配内存。因此,当像这里一样传递一个常量时,编译器也会动态创建这个字符串对象。 此外,当 STL 类的大小增加时,它们会在堆上动态分配内存。为了防止这种情况,您可以提供一个分配器,该分配器不会分配内存或从专用内存池中获取内存,或者执行您实现的任何操作。

当然,当你的代码试图超过限制时,你需要处理,但你应该以一种不可能发生的方式设计你的软件,或者至少将概率降低到绝对最小值。 例如,通过检查输入的长度等,它是否适合您的缓冲区。

最新更新