2016-03-08 61 views
-2

我傳遞緩衝器(字符*)到功能中C.用於緩衝和附加一個用C

在函數內部傳遞一個緩衝器(字符*)於函數時,我分配存儲器字符串(來自虛擬服務器的響應)。當在函數內部打印時,字符串正在從服務器發送顯示。

當試圖從功能外讀取緩衝區,我沒有得到結果,我需要:

一個。 // char * server_message; //不工作,錯誤::分段錯誤(核心轉儲)

b。 // char * server_message = calloc((BUFFER_SIZE)+ 1,sizeof(char)); //不起作用,沒有產生錯誤,下面的server_message的printf打印出一個空值:==> server_message :: || ||

c。 char * server_message = calloc((1000 * BUFFER_SIZE)+ 1,sizeof(char)); //分配超過需要的內存工作:: ==> server_message :: || 2016-03-08 12:20:13 hello there ||

我不喜歡選項c,因爲我分配的內存比我需要的多。 出於測試目的,BUFFER_SIZE當前設置爲10。

這裏是主叫部分::

write_to_server(client_socket, message, server_message); 
free(message); 
printf("\n\n==> server_message:: || %s ||\n\n", server_message); 

if (server_message != NULL) 
    free(server_message); 

這裏是write_to_server功能代碼::

void write_to_server(int file_descriptor, char* message, char* server_message) 
{ 

    char* msg = strcat(message, "\n"); 

int n_bytes = write(file_descriptor, msg, strlen(msg) + 1); 

if (n_bytes <= 0) 
{ 
    perror("write"); 
    exit(EXIT_FAILURE); 
} 

if (DEBUG_MODE) 
    printf("\nsuccessfully written %d bytes to server:: %s", n_bytes, msg); 

// char* message_back = calloc(BUFFER_SIZE + 1, sizeof(char)); 
if (server_message == NULL) 
{ 
    server_message = calloc(BUFFER_SIZE + 1, sizeof(char)); 
} 

if (server_message == NULL) 
{ 
    perror("Could not allocate memory for server_message"); 
    exit(EXIT_FAILURE); 
} 

char* tmp_message_back = calloc(BUFFER_SIZE + 1, sizeof(char)); 

if (tmp_message_back == NULL) 
{ 
    if (DEBUG_MODE) 
     perror("Could not allocate memory for tmp_message_back"); 

    exit(EXIT_FAILURE); 
} 

int n_read = 0; 
int n_total_read = 0; 

while ((n_read = read(file_descriptor, tmp_message_back, BUFFER_SIZE)) > 0) 
{ 
    n_total_read += n_read; 
    tmp_message_back[n_read] = '\0'; 

    /* 
    char* strcat(char* destination, const char* source); 

    Appends a copy of the source string to the destination string. 
    The terminating null character in destination is overwritten by the first character of source, 
    and a null-character is included at the end of the new string formed by the concatenation of both in destination. 
    */ 
    server_message = strcat(server_message, tmp_message_back); 

    // void* realloc(void* ptr, size_t size); 
    /* 
    char* new_message_back = realloc(server_message, n_total_read + (BUFFER_SIZE * sizeof(char))); 

    if (new_message_back == NULL) 
    { 
     perror("Could not allocate memory for server_message while receiving bytes from server"); 

     free(tmp_message_back); 

     return; 
    } 

    server_message = new_message_back; 
    */ 
    server_message = realloc(server_message, n_total_read + (BUFFER_SIZE * sizeof(char))); 
    server_message[n_total_read] = '\0'; 

    if (DEBUG_MODE) 
     printf("\nread %d (%d in total), size:: %zu ===> | %s |\t| %s |\n", n_read, n_total_read, strlen(server_message), server_message, tmp_message_back); 
} 

server_message = realloc(server_message, n_total_read); 

if (DEBUG_MODE) 
{ 
    printf("\n\n\n\n-- read %d in total, size:: %zu\n", n_total_read, strlen(server_message)); 
    printf("\n\nserver_message:: %s\n\n", server_message); 
} 

free(tmp_message_back); 
// free(message_back); 
} 
+2

C是通過值,即使是指針。 – 2501

+1

您正在分配參數。如果你想修改調用函數中的變量,你需要傳遞指針給它們。指針沒有什麼特別之處。 – molbdnilo

+0

這:'void write_to_server(int file_descriptor,char * message,char * server_message)'不能返回char *緩衝區。 –

回答

2

在C參數通過值傳遞。 基本上你這樣做是希望輸出爲
Hello world!

void Test(char *ptr) 
{ 
    ptr = malloc(100); // this modifies ptr but not 
         // somepointer in the main function 
    strcpy(ptr, "Hello world!"); 
} 

int main() 
{ 
    char *somepointer; // somepointer is not initialized and contains 
         // a random value 
    Test(somepointer); 
         // here the value of somepointer has not changed 

    printf("%s", somepointer); // here you try to printf a char pointer 
           // that points to a rando location 
    return 0; 
} 

這是不確定的behavioir並很可能會打印亂碼或崩潰。

你需要的是這樣的:

void Test(char **ptr) 
{ 
    *ptr = malloc(100); 
    strcpy(*ptr, "Hello world!"); 
} 

int main() 
{ 
    char *somepointer; 
    Test(&somepointer); // pas the pointer to sompointer to Test 
    printf("%s", somepointer); // now somepointer points to the memory 
           // mallocd in Test 
    return 0; 
} 
+1

這是正確的,但如果你解釋爲什麼*第一個是未定義的行爲(按值傳遞),這將是很好的。 –

+0

按價值傳遞?那爲什麼叫它指針呢? –

+0

@RogerTannous你可以傳遞一個指針ba * value *(第一種情況),或者你可以傳遞一個指針指向一個指針(第二種情況)。 –

0

我不知道,但我覺得你的問題是,你希望你的函數改變參數「Server_message」。 Server_Message是一個char數組(== char *) - 但是當讓一個函數改變你的參數時,你必須傳遞一個指向你的參數的指針。

所以不是這樣的: write_to_server(client_socket,message,server_message); 試試這個: write_to_server(client_socket,message,& server_message);

函數參數應該是char ** Server_message - 並且代碼中的一些更改也需要編譯。

也許,這有幫助。

+0

是的,我嘗試過,但我有困難解除引用char **內函數和使用malloc(realloc等)的解除引用指針。你能舉個例子嗎? –

0

好了,現在我已經改變了功能write_to_server接受的char ** p_server_message並把它稱爲使用:

write_to_server(client_socket, message, &server_message); 

我提到我的困難面對這條線:

(* p_server_message)[n_total_read] ='\ 0';

我不得不加括號,否則產生::分割故障(核心轉儲)

現在的問題只持續一個初始化的緩衝(情況下,在我的問題)::

char* server_message; 

write_to_server(client_socket, message, &server_message); 
free(message); 
printf("\n\n==> server_message:: || %s ||\n\n", server_message); 

該函數的新代碼是::

void write_to_server(int file_descriptor, char* message, char** p_server_message) 
{ 

char* msg = strcat(message, "\n"); 

int n_bytes = write(file_descriptor, msg, strlen(msg) + 1); 

if (n_bytes <= 0) 
{ 
    perror("write"); 
    exit(EXIT_FAILURE); 
} 

if (DEBUG_MODE) 
    printf("\nsuccessfully written %d bytes to server:: %s", n_bytes, msg); 

// char* message_back = calloc(BUFFER_SIZE + 1, sizeof(char)); 
if (*p_server_message == NULL) 
{ 
    *p_server_message = calloc(BUFFER_SIZE + 1, sizeof(char)); 
} 

if (*p_server_message == NULL) 
{ 
    perror("Could not allocate memory for p_server_message"); 
    exit(EXIT_FAILURE); 
} 

char* tmp_message_back = calloc(BUFFER_SIZE + 1, sizeof(char)); 

if (tmp_message_back == NULL) 
{ 
    if (DEBUG_MODE) 
     perror("Could not allocate memory for tmp_message_back"); 

    exit(EXIT_FAILURE); 
} 

int n_read = 0; 
int n_total_read = 0; 

while ((n_read = read(file_descriptor, tmp_message_back, BUFFER_SIZE)) > 0) 
{ 
    n_total_read += n_read; 
    tmp_message_back[n_read] = '\0'; 

    /* 
    char* strcat(char* destination, const char* source); 

    Appends a copy of the source string to the destination string. 
    The terminating null character in destination is overwritten by the first character of source, 
    and a null-character is included at the end of the new string formed by the concatenation of both in destination. 
    */ 
    *p_server_message = strcat(*p_server_message, tmp_message_back); 

    // void* realloc(void* ptr, size_t size); 
    /* 
    char* new_message_back = realloc(*p_server_message, n_total_read + (BUFFER_SIZE * sizeof(char))); 

    if (new_message_back == NULL) 
    { 
     perror("Could not allocate memory for p_server_message while receiving bytes from server"); 

     free(tmp_message_back); 

     return; 
    } 

    *p_server_message = new_message_back; 
    */ 
    *p_server_message = realloc(*p_server_message, n_total_read + (BUFFER_SIZE * sizeof(char))); 
    (*p_server_message)[n_total_read] = '\0'; 

    if (DEBUG_MODE) 
     printf("\nread %d (%d in total), size:: %zu ===> | %s |\t| %s |\n", n_read, n_total_read, strlen(*p_server_message), *p_server_message, tmp_message_back); 
} 

*p_server_message = realloc(*p_server_message, n_total_read); 

if (DEBUG_MODE) 
{ 
    printf("\n\n\n\n-- read %d in total, size:: %zu\n", n_total_read, strlen(*p_server_message)); 
    printf("\n\np_server_message:: %s\n\n", *p_server_message); 
} 

free(tmp_message_back); 
// free(message_back); 
} 

那麼爲什麼它仍然會產生未初始化緩衝區的分段錯誤?

我可以解決這個問題,如果我分配和初始化內存(使用calloc)在函數內部,無論緩衝區是否已經被初始化。

通過取消註釋行::

// if (*p_server_message == NULL) 
{ 
    *p_server_message = calloc(BUFFER_SIZE + 1, sizeof(char)); 
} 

但我無法理解這背後的原因。

+0

您沒有將'server_message'初始化爲'NULL',因此'* p_server_message'不是'NULL'。 – molbdnilo

+0

@molbdnilo你100%正確。我認爲如果未初始化,它會自動設置爲NULL。 –