在C语言中,可以直接将字符串指针赋值为字符串字面量吗?

5
以下程序正常工作,我很惊讶为什么会这样:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void xyz(char **value)
{
        // *value = strdup("abc");
        *value = "abc"; // <-- ??????????
}

int main(void)
{
        char *s1;

        xyz(&s1);

        printf("s1 : %s \n", s1);
}

输出:

s1 : abc

据我所知,在C语言中,如果我没有为字符串分配内存,我必须使用strdup()函数来分配内存。但在这种情况下,通过使用" "直接给字符串赋值,程序似乎也能正常运行,有人可以解释一下吗?


6
你的代码没有问题。在你的情况下,"abc"是一个字符串字面量(放置在只读段),因此你不需要为它分配空间(但你不能修改这个数据段,例如s1[0] = 'x';)。 - David Ranieri
2
谢谢。我现在明白了,“abc”在编译时存储在内存中,并且无论函数xyz()被调用多少次,它都将具有固定的地址,因此“abc”的内存不会被多次分配。 - androidFan
3个回答

7

字符串字面量并不存在于虚空之中,它们存在于程序的内存中,并拥有一个地址。

因此,您可以将该地址分配给指针。只要不通过指针尝试修改字面量,您的程序的行为是明确定义的,且不会发生任何问题。

因此,最好通过正确使用const来让编译器为您工作。尽可能将指向类型标记为const,这样您的编译器将会在尝试修改时发出警告。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void xyz(char const **value)
{
        *value = "abc";
}

int main(void)
{
        char const *s1;

        xyz(&s1);

        printf("s1 : %s \n", s1);
        s1[0] = 'a'; << Error on this line
}

4
你的程序运行正常,因为字符串字面值"abc"是字符数组,当将字符串字面值分配给指针时,实际发生的是编译器首先创建一个字符数组,然后返回数组第一个元素的地址,就像我们调用任何其他数组的名称一样。因此,在你的程序中,你已经将一个char指针的地址传递给函数xyz
*value = "abc";

对于这个语句,编译器首先在内存中创建一个字符数组,然后返回它的地址,进而将其存储在字符指针中。值得知道的是,编译器会将char数组创建在只读内存中。因此,返回的地址指向一个const char数组。任何试图修改它的值都将返回编译时错误。


1
你可以使用 char *str = "some string"; 在 C 语言中定义一个字符串,其中 str 是一个指针,它指向字符串中第一个字母的位置。

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