必须检查 curl_easy_init() 返回值是否为 nullptr,否则未检查时调用 curl_easy_setopt() 会因空指针导致段错误;设置 URL 前须确保以 http:// 或 https:// 开头;HTTPS 需链接 OpenSSL/mbedtls;WRITEFUNCTION 回调签名必须严格匹配;curl_easy_cleanup 必须成对调用且不可重复;多线程需独立句柄。
libcurl 的初始化函数 curl_easy_init() 在内存不足或内部初始化失败时会返回 nullptr,但很多示例代码直接假设它一定成功。C++ 程序中若未检查就调用 curl_easy_setopt(),会导致段错误(SIGSEGV)。
curl_easy_init() 后加 if (!curl) { /* error */ } 判断libcurl 对协议前缀敏感,CURLOPT_URL 若传入 "example.com" 或 "//cdn.example.com/file" 会被视为非法 URL,curl_easy_perform() 返回 CURLE_URL_MALFORMAT(错误码 3)。
curl_easy_setopt(curl, CURLOPT_URL, "https://www./link/4d2fe2e8601f7a8018594d98f28706f2");
CURLOPT_FOLLOWLOCATION 默认关闭,重定向(301/302)不会自动跳转;开启后需注意 CURLOPT_MAXREDIRS 防止环形重定向CURLE_UNSUPPORTED_PROTOCOL(错误码 1C++ 中若用 lambda 或普通函数做回调,容易因签名不符导致未定义行为——尤其是返回值类型错误时,libcurl 可能截断响应或提前终止传输。
size_t function(void *ptr, size_t size, size_t nmemb, void *userdata)
return size * nmemb;,不能返回 0(除非主动中止)或大于该值int 或 void 做返回类型;在类成员函数中忽略 static 修饰(导致隐式 this 参数)extern "C" size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
size_t realsize = size * nmemb;
std::string* mem = static_cast(userp);
mem->append(static_cast(contents), realsize);
return realsize;
}
int main() {
CURL* curl = curl_easy_init();
if (!curl) return -1;
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "https://www./link/4d2fe2e8601f7a8018594d98f28706f2");
curl_easy_setopt(curl, CURLOPT_W
RITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
printf("Response length: %zu\n", response.length());
}
curl_easy_cleanup(curl);
return 0;
}
libcurl 内部维护连接池、SSL 上下文、DNS 缓存等资源。curl_easy_cleanup() 是唯一释放这些资源的入口。漏掉会导致内存泄漏;重复调用(如异常路径未 guard)会引发 double-free 或崩溃。
curl_easy_init(),析构时 curl_easy_cleanup()
CURL* 句柄,不可共享curl_global_init(CURL_GLOBAL_DEFAULT),程序退出前需配对调用 curl_global_cleanup(),否则 Valgrind 会报告全局内存泄漏libcurl 的坑不在语法复杂,而在“看起来能跑通,但边界条件下悄无声息地失败”。比如 URL 缺协议、回调返回值错一位、cleanup 漏掉一次——这些都不会编译报错,却让程序在特定服务器、特定网络路径或压力测试时突然崩掉。