MST

星途 面试题库

面试题:复杂 C++ 宏定义的实现与安全隐患规避

要求实现一个复杂的宏定义,该宏定义能够实现可变参数的字符串拼接功能,并且需要考虑到可能存在的安全隐患(如宏展开导致的副作用等),并说明如何规避这些隐患。
50.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#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;
}

安全隐患及规避方法:

  1. 宏展开副作用:宏展开时可能因为参数多次求值导致意外结果。例如,如果宏参数是一个表达式,在宏展开时可能会被多次计算。
    • 规避方法:使用函数替代宏来处理复杂逻辑。这里采用string_concat函数来执行实际的字符串拼接,宏STRING_CONCAT只是起到传递参数的作用,减少宏展开带来的副作用。
  2. 内存分配失败:在string_concat函数中,malloc可能会失败。
    • 规避方法:在malloc之后检查返回值,如果返回NULL,则说明内存分配失败,需要进行相应处理,这里简单返回NULL,调用者可以根据返回值判断并采取进一步措施。
  3. 字符串溢出:如果拼接后的字符串长度超过了预期分配的内存,会导致未定义行为。
    • 规避方法:在string_concat函数中,先计算所有要拼接字符串的总长度,然后一次性分配足够的内存,避免字符串溢出。