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

2 篇文章 0 订阅

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值