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
    是在上面实现的
  • asprintf
    是sprintf的动态版本
  • 一些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
没有指向有效内存。