c - struct->char_member = ""和 strcat(struct->char_member ,"string") 有什么区别?

标签 c

我有以下代码:

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

struct test {
    char *str;
};

int main(void)
{
    struct test *p = malloc(sizeof(struct test));
    p->str = "hello world";
    printf("%s\n",p->str);
    return 0;
}

它工作正常。但是当我这样写的时候:

struct test *p = malloc(sizeof(struct test));
p->str="hello";
strcat(p->str," world");

或者这个:

struct test *p = malloc(sizeof(struct test));
strcat(p->str,"hello world");

我遇到了段错误。

我在这里找到了一些相关的解释:

You are allocating only memory for the structure itself. This includes the pointer to char, which is only 4 bytes on 32bit system, because it is part of the structure. It does NOT include memory for an unknown length of string, so if you want to have a string, you must manually allocate memory for that as well

Allocate memory for a struct with a character pointer in C

通过解释,我知道如果我想使用strcat,正确的代码应该是这样的:

struct test *p = malloc(sizeof(struct test));
p->str = malloc(size);
strcat(p->str,"hello world");

所以我的问题是为什么 p->str = "hello world"不需要分配内存,而 strcat(p->str,"hello world") 需要在使用前分配内存?

我的编译器是“gcc (Debian 4.9.2-10) 4.9.2”。我的英语很基础,请不要介意:)

最佳答案

"hello, world""hello""world" 都是字符串文字;它们都存储为 char 数组,以便它们在程序启动后立即可用,并在程序的整个生命周期内可见。

声明

p->str = "hello, world";

将字符串文字的地址复制到p->str。这适用于 printf 语句和任何其他只需要读取 字符串的东西。然而,在声明中

p->str = "hello";
strcat( p->str, " world" );

您正在尝试通过向其附加字符串"world"修改 字符串文字"hello"。字符串文字是不可修改的,并且尝试这样做会导致未定义的行为,在您的情况下这是一个段错误 - 在许多流行的桌面平台上,字符串文字保存在内存的只读部分中。

因此,您需要留出一 block 您可以写入的内存区域。您可以动态地使用

p->str = malloc( SOME_SIZE);  // enough space to store your final string
strcpy( p->str, "hello" );  // copy the contents of "hello" to the memory str points to
strcat( p->str, " world" ); // append the contents of " world" to the memory str points to

或者你可以设置p->str指向你在别处声明的数组

char buffer[SOME_SIZE];
p->str = buffer; // assigns the *address* of buffer to p->str

或者您可以在 struct 定义中将 str 声明为 char 的数组:

struct test
{
  char str[SOME_SIZE];
};

SOME_SIZE 的大小足以容纳您要存储的任何字符串。请注意,在这种情况下,p->str = "hello" 不会 起作用;您不能使用 = 运算符将数组的内容相互赋值;在这种情况下,您必须使用 strcpy

显然,使用malloccalloc 动态分配更灵活;您可以根据需要分配尽可能多的内存,并且可以根据需要使用 realloc 增加或缩小动态缓冲区 您只需要记住释放 p->str你完成了。

你仍然可以将字符串文字的地址分配给 p->str,只是要注意你不能将该地址传递给 strcpy 之类的函数strcatstrtok 或任何其他试图修改输入字符串内容的函数。

关于c - struct->char_member = ""和 strcat(struct->char_member ,"string") 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39312158/

相关文章:

c - 在c中的另一个数组中找到一个数组的元素

c - 在 C 中为套接字编写 send_all 和 recv_all 函数

c - 为什么这个链表无限期地打印最后一个元素?

c - 在从 C 调用的函数中迭代 Lua 中的表

c - C 中动态分配数组的函数 -- 两者之间有什么区别?

c++ - 如何使用按位运算符提取整数中的数字

c - 在 C 中将制表符扩展为空格?

使用 C 结构体定制订单

ANSI C 编译器可以删除延迟循环吗?

c++ - 是否可以编写一个可以采用 n 维数组的函数?