首页 > 解决方案 > 我是否冒着缓冲区溢出的风险,我将如何避免它?

问题描述

我实现了一个简单的列表结构,其中单个列表元素由以下结构定义:

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)函数将字符串附加srcdest字符串,覆盖 结尾处的终止空字节 ('\0') dest,然后添加终止空字节。字符串不能重叠,并且dest字符串必须有足够的空间用于结果。如果dest不够大,程序行为是不可预测的;缓冲区溢出是攻击安全程序的常用途径。

基本上我不知道为我的列表元素分配了多少内存。

标签: cstringc-stringsstring-literals

解决方案


这个说法:

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);

推荐阅读