我实现了一个简单的列表结构,其中单个列表元素由以下结构定义:
struct list_elem {
struct list_elem *next; // ptr to the next element
char *data; // ptr to data
};
现在,我要执行以下操作:
struct list_elem *elem;
int main() {
elem->data = "some_string";
strcat(elem->data, "another_string");
}
我担心超载,因为strcat的手册页指出:
char *strcat(char *dest, const char *src)
函数将src
字符串追加到dest
字符串,覆盖dest
末尾的终止空字节('\ 0'),然后添加一个终止的空字节。这些字符串可能不会重叠,并且dest
字符串必须有足够的空间用于结果。 如果dest
不够大,则程序行为无法预测;缓冲区溢出是攻击安全程序的常用途径。
基本上我不知道为列表元素分配了多少内存。
答案 0 :(得分:3)
此声明:
elem->data = "some_string";
使data
指针指向字符串文字"some_string"
。
在这里:
strcat(elem->data, "another_string");
您正在尝试将字符串文字"another_string"
复制到指向另一个字符串文字的指针。按照标准,尝试修改字符串文字会导致未定义的行为,因为它可能存储在只读存储器中。
您应将内存分配给data
,如下所示:
elem->data = calloc(50, 1); // sizeof (char) is 1
然后将"some_string"
复制到其中;
strcpy (elem->data, "some_string");
然后将"another_string"
连接到它:
strcat (elem->data, "another_string");
或者,您也可以使用snprintf()
:
snprintf (elem->data, 49, "%s%s", "some_string", "another_string");
编辑:
感谢@alk指出这一点。
elem
指针未指向有效内存。
您应该首先将内存分配给struct list_elem
指针elem
,如下所示:
elem = malloc (sizeof (struct list_elem));
if (elem == NULL)
exit(EXIT_FAILURE);
答案 1 :(得分:1)
您可以搜索astrxxx函数(不是标准C函数)。它们在操作时动态分配内存。 Github example implementations
astrcat
已在上面实现。asprintf
是sprintf的动态版本。注意:您应该免费分配动态分配的内存!
另外,您应该这样使用它:
struct list_elem elem; //removed *, as it can cause seg fault if not initialized. you have to initialize by using struct list_elem * elem=malloc(sizeof(struct list_elem)); or something.
int main() {
elem.data = strdup("some_string");//you must free data later
astrcat(&elem.data, "another_string");
//use it
free(elem.data);
}
首先,struct list_elem* elem
初始化为NULL
,因此必须在->
语句之前使用有效地址进行初始化。
您可以将指向数据部分的指针分配给data
,该指针不能正常修改。