我是新来的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