繁体   English   中英

分配缓冲区/字符串

[英]Allocating a buffer/string

假设我有一个如下功能:

void function(const char * str) {
    // initialize string
}

是否存在为函数初始化新字符串的“标准”方法或最佳实践? 例如,使用以下方法会有什么区别:

char * str1;

char * str2 = malloc(len);
char str3[len];

有没有时间我应该一个使用另一个? 似乎使用char * str2 = malloc(len); 将是以上方法中最灵活的。

char* str1;

这行声明一个新的字符数组。 您还不能将其用作字符串,因为您需要使用malloc,calloc或realloc将其值设置为内存块的地址。 如前所述,使用完此功能后需要释放此功能,以避免内存泄漏。

char str1[];

由于您试图声明一个没有大小的静态数组,因此该行将无法编译。

char * str3 = malloc(len);

该行与以上相同,除了您正在初始化指向内存块的指针。 现在可以将其用作长度为len-1的字符串,以为空终止符腾出空间。 同样,需要在使用结束时释放它,以避免内存泄漏。

char str4[len];

该行与上面的行相似,除了这是不能更改大小的静态数组。 “ len”必须是在编译期间已知的const整数。 当您离开声明的范围时,不需要释放这种类型的数组,并且会丢失该类型的数组。 这可以存储len-1字符串,以为空终止符腾出空间。

如上所述,可以像这样初始化此类型: char str4[] = {'n', 'e', 'w', ' ', 's', 't', 'r', 'i', 'n', 'g', '\\0'};

char* str3 = "new string";

该行与上述行不同。 该行将创建一个字符串CONSTANT,该字符串在运行时不能更改。 但是请注意,空终止符会自动添加到字符串常量的末尾。

我们喜欢以下内容:

void function(char ** str) {
    // initialize string
    *str = malloc(some length calculation);
    if (!str) return;
    strcpy(str, something); // Or maybe it isn't strcpy.
}

int main()
{
    // ...
    char * some_string = NULL;
    // ...
    function(&some_string);
    ///...
    if (some_string) {
        // do something with some_string
    }

    // ...
    free(str);
}

另一个受欢迎的模式:

char *function() {
    // initialize string
    char *str = malloc(some length calculation);
    if (!str) return str;
    strcpy(str, something); // Or maybe it isn't strcpy
    return str;
}

int main()
{
    // ...
    char *some_string = function();
    ///...
    if (some_string) {
        // do something with some_string
    }

    // ...
    free(str);
}

如果确实是const有时我们可以使用以下更简单的方法:

const char *function()
{
    if (condition)
         return "some string";
    // ...
    if (some other condition)
         return "some other string";
    // ...
    return "something completely different";
}

int main()
{
   //...
   const char *str = function();
   //...
}

这些评论都是有效的观点。

只要您正确地处理释放内存的操作,并确保实际上分配了使用malloc分配的任何内存,我就可以想到一些区别。
一种是使用malloc()可以使您更加动态并分配不同长度的字符串,而使用char str[10] (或所需的任何长度)意味着您必须提前知道预期字符串的最大长度。 如果要接受用户输入,则必须确保所接受的内容不超过该字符串所能容纳的范围,否则您将打开一个安全漏洞。

另一个可能会或可能永远不会适用于您的情况的问题是,如果使用char str[10]创建的任何字符串在函数中完成,则将在堆栈上分配该字符串。 在8位嵌入式系统上,您必须确保该字符串未越过256字节的内存边界,否则堆栈指针可能会缠绕到该内存段的开头,并可能导致某些难以诊断的问题。问题。 您必须查看程序集,以查看堆栈指针是否只有8位宽(这一次让我感到困惑,这是一个奇怪的调试问题。这不是字符串问题,而是大型结构问题,但是字符串也可以做到)。 malloc()将位于堆上,也就是说,如果嵌入式处理器设置了堆(在8位上不常见,但有可能)。 注意:字符串的长度不必为256个字节,但是它之前可以包含更多的局部变量,否则该函数可能位于调用堆栈的下方,从而将一个较短的字符串推入边界。

手动内存管理始终是一个棘手的问题,因此我希望尽可能多地使用堆栈分配,但这实际上取决于您的应用程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM