2014-12-05 99 views
0

我在理解「char *」如何在不同文件中工作時遇到問題。例如,我有一個簡單的CURL函數,可以幫助我將數據發送到其他HTTP WEB服務。但我也需要收到,這裏是位於「curlate.h」的功能:ANSI C - 將函數中的數據傳遞給CHAR指針

#include <stdio.h> 
#include <curl/curl.h> 

struct string 
{ 
    char * ptr; 
    size_t len; 
}; 

void init_string(struct string * s) 
{ 
    s - > len = 0; 
    s - > ptr = malloc(s - > len + 1); 
    if (s - > ptr == NULL) 
    { 
     fprintf(stderr, "malloc() failed\n"); 
     exit(EXIT_FAILURE); 
    } 
    s - > ptr[0] = '\0'; 
} 

size_t writefunc(void * ptr, size_t size, size_t nmemb, struct string * s) 
{ 
    size_t new_len = s - > len + size * nmemb; 
    s - > ptr = realloc(s - > ptr, new_len + 1); 
    if (s - > ptr == NULL) 
    { 
     fprintf(stderr, "realloc() failed\n"); 
     exit(EXIT_FAILURE); 
    } 
    memcpy(s - > ptr + s - > len, ptr, size * nmemb); 
    s - > ptr[new_len] = '\0'; 
    s - > len = new_len; 

    return size * nmemb; 
} 

char* curlate_and_print(char url[]) 
{ 
    //printf("Curlating ... %s : ",url); 
    CURL *curl; 
    CURLcode res; 

    struct string s; 
    init_string(&s); 

    curl = curl_easy_init(); 
    if(curl) 
    { 
     curl_easy_setopt(curl, CURLOPT_URL, url); 
     /* example.com is redirected, so we tell libcurl to follow redirection */ 
     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); 
     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); 

     /* Perform the request, res will get the return code */ 
     res = curl_easy_perform(curl); 

     /* Check for errors */ 
     if(res != CURLE_OK) 
     { 
      curl_easy_strerror(res); 
     } 
     else 
     { 
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); 
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 
      res = curl_easy_perform(curl); 

      // *** THE FUNCTION PRINTS THE RESULT HERE WITH NO PROBLEM 
      printf("\nCURL_STRING BEGIN\n%s\nCURL_STRING END\n", s.ptr); 
      free(s.ptr); 
     } 

     /* always cleanup */ 
     curl_easy_cleanup(curl); 

    } 

    return s.ptr; 
} 

該腳本,沒有任何問題,這是印刷的東西,但我也回這樣return s.ptr;的價值,我想在main.c中使用此字符串數據。

現在,在main.c我打電話curlate_and_print函數,它是打印數據,但無論我做什麼,我都不能在main.c中打印它!

char* content2 = curlate_and_print(link_to_curlate);

爲什麼在地球char* content2main.c空? s.ptr不爲空,它具有內容結果。

這是我在main.c

if(debug >= 1) printf("Testing, curlating %s : \n",link_to_curlate); 
// in content2 sa se verse output-ul din curlate_and_print(link_to_curlate); 
char* content2 = curlate_and_print(link_to_curlate); 

printf("\n"); 

printf(">%s\n",content2); // *** I GET EMPTY STRING 
printf(">%s\n",content2); // *** I GET EMPTY STRING 
printf(">%s\n",content2); // *** I GET EMPTY STRING 
printf(">%s\n",content2); // *** I GET EMPTY STRING 
printf(">%s\n",content2); // *** I GET EMPTY STRING 

我怎麼能解決這個問題?

問題是,我認爲我不明白char* content2 = "asdasd"是幹什麼的,對我來說就像是在用JAVA'String java =「asdasd」;'說的,儘管我知道這是一個char pointer

謝謝。

回答

1

問題是當你第一次打印字符串(在curlate_and_print之內),你立即釋放字符串緩衝區(呼叫free(s.ptr))。釋放它後,試圖解引用指針會導致未定義的行爲。在你的情況下,字符串顯示爲空。

+0

是的,你是對的,非常感謝你的幫助 – Damian 2014-12-05 19:00:03

1

試着改變你的函數的返回語句如下:

return strdup(s.ptr); 

這會自動malloc的字符串,但你不必擔心。它基本上會爲你複製字符串。 s.ptr是一個局部變量;如果你想返回它使它堆分配,並說return s->ptr。您必須這樣做,因爲s.ptr是本地的,因此在函數返回後,不能再訪問由s.ptr指向的堆棧內存。

+0

我剛剛評論了1行// free(s.ptr); , 非常感謝您的幫助 – Damian 2014-12-05 18:59:43