#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
// 定义宏实现可变参数的字符串拼接
#define STRING_CONCAT(...) string_concat(__VA_ARGS__, NULL)
// 实际执行字符串拼接的函数
char* string_concat(const char* first, ...) {
va_list args;
va_start(args, first);
const char* arg;
size_t total_length = strlen(first);
// 计算总长度
for (arg = va_arg(args, const char*); arg != NULL; arg = va_arg(args, const char*)) {
total_length += strlen(arg);
}
va_end(args);
// 分配内存
char* result = (char*)malloc(total_length + 1);
if (result == NULL) {
return NULL;
}
strcpy(result, first);
char* dest = result + strlen(first);
va_start(args, first);
// 拼接字符串
for (arg = va_arg(args, const char*); arg != NULL; arg = va_arg(args, const char*)) {
strcpy(dest, arg);
dest += strlen(arg);
}
va_end(args);
result[total_length] = '\0';
return result;
}
安全隐患及规避方法:
- 宏展开副作用:宏展开时可能因为参数多次求值导致意外结果。例如,如果宏参数是一个表达式,在宏展开时可能会被多次计算。
- 规避方法:使用函数替代宏来处理复杂逻辑。这里采用
string_concat
函数来执行实际的字符串拼接,宏STRING_CONCAT
只是起到传递参数的作用,减少宏展开带来的副作用。
- 内存分配失败:在
string_concat
函数中,malloc
可能会失败。
- 规避方法:在
malloc
之后检查返回值,如果返回NULL
,则说明内存分配失败,需要进行相应处理,这里简单返回NULL
,调用者可以根据返回值判断并采取进一步措施。
- 字符串溢出:如果拼接后的字符串长度超过了预期分配的内存,会导致未定义行为。
- 规避方法:在
string_concat
函数中,先计算所有要拼接字符串的总长度,然后一次性分配足够的内存,避免字符串溢出。