我無法弄清我的代碼的奇怪行爲。 基本上,程序監聽一個TCP端口,獲取啓動/停止命令後,它創建一個捲曲線程並開始下載流。 問題是,每次下載流時,程序都會在共享內存中增長。在許多下載之後,程序停止工作。 - 它接受啓動/停止命令,但只下載一小塊數據。我認爲,有一些內存泄漏。 代碼:從Valgrind的C線程和捲曲內存泄漏
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <curl/curl.h>
#define MY_PORT 8888
#define MAXBUF 1024
int hour=1,min=1,sec=1,year=0,month=0,mday=0;
int stop=0;
static void daemon();
CURL *curl;
CURLcode res;
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written;
written = fwrite(ptr, size, nmemb, stream);
if(stop)
return -1;
return written;
}
void * curl_thread(){
FILE *fp;
char format[] = "/root/test/archive_%d-%s-%s_%s.%s.%s.mp3";
char outfilename[sizeof format+100];
char mi[3];
char mth[3];
char dom[3];
char hrs[3];
char secs[3];
sprintf(mth, "%d", month);
sprintf(dom, "%d", mday);
sprintf(hrs, "%d", hour);
sprintf(mi, "%d", min);
sprintf(secs, "%d", sec);
if (month<10){
sprintf(mth, "0%d", month);}
if (mday<10){
sprintf(dom, "0%d", mday); }
if (hour<10){
sprintf(hrs, "0%d", hour); }
if (min<10){
sprintf(mi, "0%d", min);}
if (sec<10){
sprintf(secs, "0%d", sec);}
sprintf(outfilename,format,year,mth,dom,hrs,mi,secs);
curl = curl_easy_init();
if(curl) {
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8000/stream.mp3");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl capture");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
stop=0;
pthread_exit(0);
}
void time_date(void){
time_t rawtime;
time (&rawtime);
struct tm *tm_struct = localtime(&rawtime);
hour = tm_struct->tm_hour;
min = tm_struct->tm_min;
sec= tm_struct->tm_sec;
year=tm_struct->tm_year + 1900;
month=tm_struct->tm_mon + 1;
mday=tm_struct->tm_mday;
}
void daemon(){
pid_t mypid;
FILE *pid;
mypid=fork();
if (mypid){
pid=fopen("acapt.pid","w");
fprintf(pid,"%i",mypid);
exit (0);
}
}
int main(int Count, char *Strings[])
{
daemon();
time_date();
int thread=0;
int sockfd;
struct sockaddr_in self;
char buffer[MAXBUF];
char buff[MAXBUF];
//---Create streaming socket---*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Socket");
exit(errno);
}
///Initialize address/port structure---*/
bzero(&self, sizeof(self));
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = INADDR_ANY;//*---Assign a port number to the socket---*/
if (bind(sockfd, (struct sockaddr*)&self, sizeof(self)) != 0)
{
perror("socket--bind");
exit(errno);
}
///*---Make it a "listening socket"---*/
if (listen(sockfd, 20) != 0)
{
perror("socket--listen");
exit(errno);
}
//*---Forever... ---*/
while (1)
{ int clientfd;
struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);
//*---accept a connection (creating a data pipe)---*/
clientfd = accept(sockfd, (struct sockaddr*)&client_addr,&addrlen);
//*---Echo back anything sent---*/
recv(clientfd, buffer, MAXBUF, 0);
if (strcmp(buffer, "start\r\n")==0&&!thread){
close(clientfd);
sleep(5);
time_date();
pthread_t tid;
pthread_create(&tid,NULL,curl_thread,NULL);
thread=1;
}
if (strcmp(buffer, "stop\r\n")==0&&thread){
close(clientfd);
stop=1;
thread=0;
curl_global_cleanup();
}
memset (buffer, '\0', MAXBUF);
//*---Close data connection---*/
close(clientfd);
}
//---Clean up (should never get here!)---*/
close(sockfd);
return 0;
}
信息一個開始/停止後:
HEAP SUMMARY:
in use at exit: 4,897 bytes in 58 blocks total heap usage: 2,987 allocs, 2,929 frees, 200,756 bytes allocated 576 bytes in 2 blocks are possibly lost in loss record 16 of 20
at 0x4C272B8: calloc (vg_replace_malloc.c:566)
by 0x401128E: _dl_allocate_tls (dl-tls.c:300)
by 0x4E36483: [email protected]@GLIBC_2.2.5 (allocatestack.c:580)
by 0x4016A2: main (in /root/test/testas) LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 576 bytes in 2 blocks
still reachable: 4,321 bytes in 56 blocks
suppressed: 0 bytes in 0 blocks
Reachable blocks (those to which a pointer was found) are not shown.
To see them, rerun with: --leak-check=full --show-reachable=yes
For counts of detected and suppressed errors, rerun with: -v
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 6)
謝謝你的幫助。
我不確定它是否是你的內存泄漏的根本原因,但你的'write_data()'的返回值似乎不正確。在[fwrite](http://pubs.opengroup.org/onlinepubs/009695399/functions/fwrite.html)手冊中,它提到返回值是寫入元素的數量。但是從[curl](http://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html)手冊中,它預期返回的字節數。實際的字節應該是'size * nmemb'。當然,如果'size'是1個字節的大小,上面的語句是沒有意義的。 – SSC 2014-10-31 08:01:50
完全不相關,但%02d可能是你想要做單sprintf()調用,而不是兩個... – 2014-10-31 10:07:30