在堆或堆栈上分配的动态创建的字符串 - C

Dynamically created string allocated on heap or stack - C

上下文

我正在尝试在 C++ 中获取 C 字符串而不在堆上分配内存,并在测试中遇到了这个问题:

#include <stddef.h>
#include <stdlib.h>

char* get_empty_c_string(size_t length) {
    char buffer[length];
    char *string = buffer;

    for (size_t i = 0; i ^ length; i++) *(string + i) = '[=10=]';

    return string;
}

int main(void) {
    char *string = get_empty_c_string(20u); // Allocated on heap?
                                            // or stack?
    return 0;
}

问题

返回的C字符串是分配在堆上还是栈上?

据我所知:

正如@PaulMcKenzie 指出的那样,您对 get_empty_c_string() 的实现将无法编译:本质上,数组作为函数的 temporary/instance 变量需要在编译之前为其定义静态大小时间。这是因为该内存量在函数调用时被压入堆栈

我可以看出您正在尝试将动态内存分配作为函数本身的一部分,这就是您需要此类堆分配器的原因。

数组 buffer 是一个 可变长度数组 (VLA),这意味着它的大小是在运行时确定的。作为函数的局部变量驻留在堆栈上。然后指针 string 指向该数组,并返回该指针。因为返回的指针指向超出范围的本地堆栈变量,所以尝试使用该指针将调用 undefined behavior.

另请注意,VLA 是 C 语言独有的功能。

在标准 C++ 中无法获得自动存储持续时间的运行时大小的内存(通常映射到堆栈内存)。

因此无法在堆栈上获得任意长度的适当字符串。您只能分配一个最大大小的缓冲区,并在程序中使用最大长度的字符串。 (类似的事情通常由 std::string 完成,即所谓的 短字符串优化 。)

此外,您不能 return 指针或对函数中具有自动存储持续时间的变量的引用。当函数 returns 变量被销毁并且 pointer/reference 变得无效。您只能在函数 returns 之前使用堆栈分配。但是,您可以 return 变量按值。