我有以下代码:
#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
。
显然,使用malloc
或calloc
动态分配更灵活;您可以根据需要分配尽可能多的内存,并且可以根据需要使用 realloc
增加或缩小动态缓冲区 您只需要记住释放 p->str
你完成了。
你仍然可以将字符串文字的地址分配给 p->str
,只是要注意你不能将该地址传递给 strcpy
或 之类的函数strcat
或 strtok
或任何其他试图修改输入字符串内容的函数。
关于c - struct->char_member = ""和 strcat(struct->char_member ,"string") 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39312158/