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

时间:2019-12-13 02:42:20

标签: c++ c memory allocation

上下文

我正在尝试在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) = '\0';

    return string;
}

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

问题

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

据我所知:

  • 堆分配使用callocmallocrealloc C标准函数或newnew[] C ++关键字进行。

  • 在大多数其他情况下,堆栈分配。

3 个答案:

答案 0 :(得分:1)

数组buffer可变长度数组(VLA),这意味着其大小是在运行时确定的。由于函数局部变量位于堆栈上。然后,指针string指向该数组,并返回该指针。并且由于返回的指针指向超出范围的局部堆栈变量,因此尝试使用该指针将调用undefined behavior

另外,请注意,VLA是仅C的功能。

答案 1 :(得分:1)

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

因此,不能在堆栈上获得任何长度的正确字符串。您只能分配最大大小的缓冲区,并在程序中使用不超过该长度的字符串。 (std::string通常通过所谓的短字符串优化完成类似的操作。)

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

答案 2 :(得分:0)

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

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

相关问题