C - 字符串最佳实践

3
以下哪项是处理C字符串的最佳实践?
char full_name[] = "foo boo";
char * full_name = "foo boo";

从安全角度来看,每个选项的优缺点是什么?

3
你在 Stack Overflow 上搜索过它们吗? - ameyCU
1
https://dev59.com/NXI-5IYBdhLWcg3wu7FU - Spikatrix
请注意,这些问题是不同的。我并不是在问背后发生了什么,我很明确地在问哪种更安全使用。 - Malo Polsky
3个回答

4

处理字符串是一项复杂的任务,您展示的选项没有任何优缺点。这实际上取决于您想要实现的解决方案。

char full_name[] = "foo boo";

是一个具有以下内容的数组

{'f', 'o', 'o', ' ', 'b', 'o', 'o', '\0'}

你可以修改它,但它不能增长,而且

char *full_name = "foo boo";

是一个字符串字面量,你不能修改它也不能让它增长,最好像这样定义

const char *full_name = "foo boo";

尽管这并不能完全防止修改它,但可以帮助避免意外修改。
修改字符串常量是可能的,但是错误的,因为它会引发未定义行为。

1
char *full_name = "foo boo"; 将字面值赋给变量(用字面值初始化变量)。您无法更改字面字符串,但可以将另一个字面值或变量分配给该变量,例如 full_name = my_name; - Paul Ogilvie
@PaulOgilvie 严格来说,你可以更改它,只是这是未定义的行为 - Iharob Al Asimi
我的意思是,由于 char *full_name; 是一个指针变量,因此您可以将不同(其他)变量分配给它。 它们可以是文字,也可以是包含从文件中读取的字符串的 malloc 缓冲区。 这不是 UB。 - Paul Ogilvie
好的,我明白了,你的意思是说 char *full_name 实际上是一个指针,因此可以重新分配它。这是使用 const 的另一个原因,即使你使用 const 进行 full_name = malloc(some_size),你仍需要显式地转换掉 const,以最小化更改字符串字面量的潜在 未定义行为。例如 const char *full_name = "Something"; if (something_else == true) {full_name = strdup("Something Else");} free(full_name); 将至少发出警告。请注意,如果 something_else == false -> 未定义行为 - Iharob Al Asimi

4
在C语言中,字符串可以使用字符指针或者字符数组来引用。
将字符串作为字符数组来处理。
char str[4] = "GfG"; /*One extra for string terminator*/
/*    OR    */
char str[4] = {‘G’, ‘f’, ‘G’, '\0'}; /* '\0' is string terminator */

当字符串被声明为字符数组时,它们像C中的其他类型数组一样存储。例如,如果str[]是一个auto variable,那么字符串将存储在stack segment中,如果它是一个globalstatic变量,则存储在data segment中等。 使用字符指针的字符串 使用字符指针,字符串可以以两种方式存储:
  1. Read-only string in a shared segment.

    When string value is directly assigned to a pointer, in most of the compilers, it’s stored in a read only block (generally in data segment) that is shared among functions.

    char *str  =  "GfG";  
    

    In the above line “GfG” is stored in a shared read-only location, but pointer str is stored in a read-write memory. You can change str to point something else but cannot change value at present str. So this kind of string should only be used when we don’t want to modify string at a later stage in program.

  2. Dynamically allocated in heap segment.

    Strings are stored like other dynamically allocated things in C and can be shared among functions.

    char *str; 
    int size = 4; /*one extra for ‘\0’*/ 
    str = malloc(size);
    *(str+0) = 'G'; 
    *(str+1) = 'f';  
    *(str+2) = 'G';  
    *(str+3) = '\0';
    

了解更多细节


-4
如果从安全角度考虑,不要使用指针。尽量始终使用非指针变量。指针直接访问内存地址,这可能导致内存泄漏问题、内存黑客问题等。

9
指针是 C 语言中重要的部分,对于任何复杂的程序都是必需的。更好的做法是学会正确使用它们(学习 const 正确性,拥有明确的所有权等),而不是过度恐惧地避免使用它们。 - user694733
如果您不想使用指针,请使用另一种编程语言。此外,上述两个选项中的任何一个都使用了指针,您是否建议在 [tag:c] 中使用不涉及指针的字符串处理方式? - Iharob Al Asimi
这是一个有趣的观点,我无法想象你会如何处理它?你是否实际上在C / C ++ / Objective C中实现了不使用指针的系统? - wmorrison365
@wmorrison365 在C++中,你可以避免使用指针,从而放弃所有的好处。虽然,良好编写的C++类会在内部使用指针,例如共享数据,但这并不是一件简单的事情,但它是可能的例如查看QString。因此,在C++中,指针仍然非常重要。 - Iharob Al Asimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接