VS2005 使用静态libcurl库编译的工程调用free()报堆错误

curl中有很多地方使用 strdup,但windows下已经废弃了“strdup”,而要求用 “_strdup” 替代 (

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strdup-wcsdup?view=vs-2019)。

这就是造成libcurl静态库调用free()时产生异常的原因。

    其实 libcurl 已经考虑到不同平台下内存分配释放函数的差异,库实现中的malloc,calloc,strdup,free等函数,实际调用的是easy.c中定义的Curl_cmalloc,Curl_ccalloc,Curl_cstrdup,Curl_cfree 函数指针,初始化函数global_init()会定义这些函数指针。


/**
 * curl_global_init() globally initializes curl given a bitwise set of the
 * different features of what to initialize.
 */
static CURLcode global_init(long flags, bool memoryfuncs)
{
  if(initialized++)
    return CURLE_OK;

  if(memoryfuncs) {
    /* Setup the default memory functions here (again) */
    Curl_cmalloc = (curl_malloc_callback)malloc;
    Curl_cfree = (curl_free_callback)free;
    Curl_crealloc = (curl_realloc_callback)realloc;
    Curl_cstrdup = (curl_strdup_callback)system_strdup;
    Curl_ccalloc = (curl_calloc_callback)calloc;
#if defined(WIN32) && defined(UNICODE)
    Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
  }

  if(!Curl_ssl_init()) {
    DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
    goto fail;
  }

#ifdef WIN32
  if(Curl_win32_init(flags)) {
    DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
    goto fail;
  }
#endif

    其中,只有Curl_cstrdup的默认值比较特别,它指向 system_strdup 。可以看出,只有在_WIN32_WCE 定义的条件下 strdup指向 _strdup,否则调用curlx_strdup或strdup ,而由于config-win32.h中定义#define HAVE_STRDUP 1,所以用VS编译肯定不会用curlx_strdup,那就只有strdup了。

  #if defined(_WIN32_WCE)
  #define system_strdup _strdup
  #elif !defined(HAVE_STRDUP)
  #define system_strdup curlx_strdup
  #else
  #define system_strdup strdup
  #endif

     我们在这儿增加WIN32判断条件,这样在 visual studio下调用strdup的地方会指向我们期望的安全函数 _strdup。

- #if defined(_WIN32_WCE)
+ #if defined(_WIN32_WCE) || defined(_WIN32) ||defined(WIN32)
  #define system_strdup _strdup
  #elif !defined(HAVE_STRDUP)
  #define system_strdup curlx_strdup
  #else
  #define system_strdup strdup
  #endif

你可能感兴趣的:(libcurl,MFC,libcurl,vs2005,curl,visual,studio,code)