C 我是否有缓冲区溢出的风险?如何避免?
我实现了一个简单的列表结构,其中单个列表元素由以下结构定义:C 我是否有缓冲区溢出的风险?如何避免?,c,string,c-strings,string-literals,C,String,C Strings,String Literals,我实现了一个简单的列表结构,其中单个列表元素由以下结构定义: 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(e
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
不够大,则程序行为是不可预测的;缓冲区溢出是攻击安全程序的最常用途径
基本上,我不知道为我的列表元素分配了多少内存。您可以搜索AstXXX函数(,不是标准的C函数)。它们在运行时动态分配内存。
是在上面实现的astcat
是sprintf的动态版本asprintf
- 一些GNU编译器提供了更多的功能
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);
}
elem->data = calloc(50, 1); // sizeof (char) is 1
elem = malloc (sizeof (struct list_elem));
if (elem == NULL)
exit(EXIT_FAILURE);
首先,struct list\u elem*elem
被初始化为NULL
,因此它必须在->
语句之前用有效地址初始化。
您可以将指向数据节的指针指定给无法正常修改的数据。此语句:
elem->data = "some_string";
使数据
指针指向字符串文字“某些字符串”
在这里:
strcat(elem->data, "another_string");
您正试图将字符串文字“另一个字符串”
复制到指向另一个字符串文字的指针。根据标准,试图修改字符串文字会导致未定义的行为,因为它可能存储在只读存储器中
您应该为数据分配内存,如下所示:
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);
}
elem->data = calloc(50, 1); // sizeof (char) is 1
elem = malloc (sizeof (struct list_elem));
if (elem == NULL)
exit(EXIT_FAILURE);
然后将“some_string”
复制到它
strcpy (elem->data, "some_string");
然后将“另一个字符串”连接到它:
strcat (elem->data, "another_string");
或者,也可以使用snprintf()
:
snprintf (elem->data, 49, "%s%s", "some_string", "another_string");
编辑:
感谢@alk指出这一点
elem
指针未指向有效内存。
您应该首先将内存分配给结构列表元素
指针元素
,如下所示:
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);
}
elem->data = calloc(50, 1); // sizeof (char) is 1
elem = malloc (sizeof (struct list_elem));
if (elem == NULL)
exit(EXIT_FAILURE);
只有当data
是malloc
的结果时,才有办法知道分配了多少字节:对于列表元素:没有分配内存elem
为NULL
。对于您的字符串:分配了12个字节(“s”、“o”、“m”、“e”、“s”、“t”、“r”、“i”、“n”、“g”、“0”)。他不需要在结构中使用字符数组。空间可以在连接时分配itself@mangusta:“空间可以在连接本身上分配”请问您到底想表达什么?请注意,astcat()
和aprintf()
不是标准的C,也不是。strdup()
是。struct list_elem*elem
没有初始化“它是,作为一个全局变量,它被初始化为NULL
,这实际上没有多大帮助。请注意,根据OP的代码elem
没有指向有效内存。