我是新來的c。只需要對c中的字符數組(或字符串)有個疑問:當我想在C中創建字符數組時,是否必須同時給出大小?C中的字符數組
因爲我們可能不知道,我們實際需要的尺寸。例如客戶端 - 服務器程序的,如果我們要聲明一個字符數組服務器程序接收來自客戶端程序的消息,但我們不知道消息的大小,我們可以做這樣的:
char buffer[1000];
recv(fd,buffer, 1000, 0);
但是,如果實際的消息僅僅是長度10會造成大量浪費的內存?
我是新來的c。只需要對c中的字符數組(或字符串)有個疑問:當我想在C中創建字符數組時,是否必須同時給出大小?C中的字符數組
因爲我們可能不知道,我們實際需要的尺寸。例如客戶端 - 服務器程序的,如果我們要聲明一個字符數組服務器程序接收來自客戶端程序的消息,但我們不知道消息的大小,我們可以做這樣的:
char buffer[1000];
recv(fd,buffer, 1000, 0);
但是,如果實際的消息僅僅是長度10會造成大量浪費的內存?
是的,你必須決定的尺寸提前,就算你使用malloc。
當從插座讀,如在例如,通常使用具有合理的大小的緩衝器,並且調度數據中的其它結構,一旦你消費它。在任何情況下,1000個字節是不是這麼多的內存浪費,可以肯定的是不是每次從一些內存管理:)問一個字節更快
是的,你必須給,如果你不初始化字符大小數組在聲明時。解決問題的更好方法是在運行時確定緩衝區的最佳大小並動態分配內存。
你問的是如何動態調整緩衝區大小。這是通過動態分配完成的,例如使用malloc()
- 內存分配器。使用它會給你一個重要的責任,當你完成使用緩衝區時,你必須必須自己將它返回給系統。如果使用malloc()[或calloc()],則返回free()
。
例如:
char *buffer; // pointer to a buffer -- essentially an unsized array
buffer = (char *)malloc(size);
// use the buffer ...
free(buffer); // return the buffer -- do NOT use it any more!
唯一的問題留待解決的是如何確定你需要的大小。如果recv()的數據暗示了大小,你需要將通信分成兩個recv()調用:首先獲得所有數據包的最小大小,然後分配完整緩衝區,然後recv'其餘的。
當你不知道輸入數據的確切金額,具體操作如下:
複製從緩衝器到存儲
4.1數據如果沒有ENO存放在存儲器中,重新分配存儲器(例如,以兩倍大小大於它是在這一點上)
執行步驟3和4,除非「流的末尾」
你的存儲包含的數據了。
如果您不知道大小的先驗,那麼你別無選擇,只能動態地使用malloc(或其他等效機制在您所選擇的語言來創建它。)
size_t buffer_size = ...; /* read from a DEFINE or from a config file */
char * buffer = malloc(sizeof(char) * (buffer_size + 1));
創建尺寸m
的緩衝區,但僅在接收到尺寸n
的輸入字符串與n < m
不是存儲器的浪費,但工程折衷。
如果您創建的緩衝區的大小接近預期輸入,那麼您可能需要爲其中m >> n
多次重複填充緩衝區。通常情況下,對緩衝區的迭代與I/O操作綁定在一起,所以現在你可能會節省一些字節(這在今天的硬件中完全沒有),而犧牲潛在地增加另一端的問題。特別適用於客戶端服務器應用程序。如果我們討論資源受限的嵌入式系統,那將是另一回事。
你應該擔心讓你的算法正確和可靠。那麼你擔心,如果可以的話,在這裏和那裏削減幾個字節。
對我來說,我寧願創建一個比平均輸入大2到10倍的緩衝區(不是你的情況中的最小輸入,而是平均值),假設我的輸入往往有一個慢的標準偏差在尺寸方面。否則,我會選擇20倍以上的尺寸(特別是如果內存很便宜並且這樣可以最大限度地降低磁盤或NIC卡的尺寸)。
在最基本的設置中,通常會獲得緩衝區的大小爲配置項從文件讀取(或作爲參數傳遞),如果沒有提供,則默認爲。然後您可以根據觀察到的輸入大小調整緩衝區的大小。
更精細的算法(比如TCP)在運行時調整其緩衝區的大小,以更好地適應其大小可能隨時間變化的輸入。
即使您使用malloc,也必須先定義大小!因此,而不是你給了大量能夠接受的消息一樣的:
int buffer[2000];
在小消息或大可以重新分配其釋放未使用的位置或佔用未使用的位置的情況下
example:
int main()
{
char *str;
/* Initial memory allocation */
str = (char *) malloc(15);
strcpy(str, "tutorialspoint");
printf("String = %s, Address = %u\n", str, str);
/* Reallocating memory */
str = (char *) realloc(str, 25);
strcat(str, ".com");
printf("String = %s, Address = %u\n", str, str);
free(str);
return(0);
}
注意:確保包含stdlib.h庫
搜索'C中的動態內存分配' –
這將成爲內存的「浪費」,因爲您只是因爲無法期望知道您有多少需要提前預約,所以你會預留e儘管如此,儘管你仍然意識到你實際上可能需要更多的東西,但它應該能夠滿足你的大部分情況。 –
在C++中你不會有這個問題,它有一個內置的字符串類型,而不是使用字符數組。當然,你可能會遇到很多不同的問題,但也許你應該看看。 – john