c - 我是否冒着缓冲区溢出的风险,我将如何避免它?
问题描述
我实现了一个简单的列表结构,其中单个列表元素由以下结构定义:
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
字符串,覆盖 结尾处的终止空字节 ('\0')dest
,然后添加终止空字节。字符串不能重叠,并且dest
字符串必须有足够的空间用于结果。如果dest
不够大,程序行为是不可预测的;缓冲区溢出是攻击安全程序的常用途径。
基本上我不知道为我的列表元素分配了多少内存。
解决方案
这个说法:
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);
推荐阅读
- dask - 尝试使用 gcsfs 写入 Google Cloud 时出现“块写入低于最小大小”
- django - 如何在 Django 相关字段查询中执行天数计算
- uefi - AllocatePages 将内存类型的 EFI_INVALID_PARAMETER 返回为 EfiConventionalMemory?
- wix - 在“产品:*”部分中未解决对符号“属性:VS2019DEVENV”的引用
- firebase - 错误:没有名为“合并”的命名参数
- android - 无法使用毕加索从 URI 加载图像
- modelica - modelica 中的模型终止错误(模型的结束线错误)
- html - 如何用点将 li 与中心对齐
- html - 如何固定顶部和侧面导航栏?HTML-CSS
- libgdx - libgdx DragListener 取消