【问题标题】:c++ - sprintf error "variable may be unsafe" (C4996)... alternatives?c++ - sprintf 错误“变量可能不安全”(C4996)......替代品?
【发布时间】:2018-07-06 19:46:28
【问题描述】:

这是我的代码:

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4996)
#pragma comment(lib,"ws2_32.lib")
#include "stdafx.h"
#include <assert.h>
#include "Bootpd.h"
#include <iostream>
#include <string>
#include <iphlpapi.h>


char *MAC() {
    PIP_ADAPTER_INFO AdapterInfo;
    DWORD dwBufLen = sizeof(AdapterInfo);
    char *mac_addr = (char*)malloc(20);

    AdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
    assert(AdapterInfo != NULL); //Error allocating memory

    // Make an initial call to GetAdaptersInfo to get the necessary size into the dwBufLen variable
    if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == ERROR_BUFFER_OVERFLOW) {
        AdapterInfo = (IP_ADAPTER_INFO *)malloc(dwBufLen);
        assert(AdapterInfo != NULL);
    }

    if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == NO_ERROR) {
        PIP_ADAPTER_INFO info = AdapterInfo; //Copy information
        sprintf(mac_addr, "%02X:%02X:%02X:%02X:%02X:%02X",
            info->Address[0], info->Address[1],
            info->Address[2], info->Address[3],
            info->Address[4], info->Address[5]);
    }
    free(AdapterInfo);
    return mac_addr;
}

我在 Windows 10 上使用 VS 2015。我正在尝试将网络适配器的 MAC 地址信息格式化为 MAC 地址 (aa:bb:cc:dd:ee:ff)。我已经尝试在我的#include 语句上方定义_CRT_SECURE_NO_WARNINGS 并禁用警告4996,但没有成功。有什么我遗漏的吗,或者有人知道解决sprintf 错误variable may be unsafe 的不同方法吗?谢谢。

【问题讨论】:

  • 关闭警告可能是错误的选择。是什么导致了警告?这是%02XAddress[0] 的类型不匹配吗?
  • “当编译器遇到标记为已弃用的函数或变量时,会发生 C4996。” 来源:msdn.microsoft.com/en-us/library/ttcz0bys.aspx 因为您没有包含完整的消息文本很难进一步帮助您。
  • 既然是 C++,为什么不使用std::string 和朋友们,而不是使用malloc 进行所有这些丑陋的手动分配呢?有combining multiple strings together with formatting的方式。
  • 附带说明,您正在错误地初始化dwBufLen。您将其设置为sizeof(AdapterInfo),但AdapterInfo 是一个指针,因此dwBufLen 将是4 或8,具体取决于32 位或64 位编译。但随后您使用malloc() 分配sizeof(IP_ADAPTER_INFO) 字节并忽略dwBufLen。因此,您对GetAdaptersInfo() 的第一次调用是关于真实缓冲区大小的,传递的缓冲区大小比实际缓冲区小得多。将dwBufLen 初始化为sizeof(*AdapterInfo)sizeof(IP_ADAPTER_INFO),然后将dwBufLen 传递给malloc() 的第一次调用。
  • assert.h 是 C++ 中已弃用的 C 兼容性标头,请改用 cassert 和朋友。您也没有包含sprintfmalloc/freecstdiocstdlib 所需的标头。您还必须使用来自 std 命名空间(例如 std::sprintfstd::mallocstd::free)的 C++ 标头等效函数以符合标准,因为不需要实现来放置函数定义进入全局命名空间。使用 C++ 编程时,应始终使用 nullptr 而不是 NULL 以获得更好的类型安全性。

标签: c++ windows networking adapter bootp


【解决方案1】:

编译器抱怨可能会超出 mac_addr 数组。给 sprintf_s 一个机会。 https://en.cppreference.com/w/c/io/fprintf

【讨论】:

    猜你喜欢
    • 2012-11-13
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 2012-12-09
    相关资源
    最近更新 更多