缓冲区还是Realloc? [英] Buffer or Realloc?

查看:55
本文介绍了缓冲区还是Realloc?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常更好的设置一个缓冲区(固定大小的数组)并读取

并写入该

缓冲区,即使它大于写到它?或者它是否更好地分配内存并将其重新分配给每次写入的内容大小?
?换句话说,在决定使用固定大小的缓冲区或分配内存

空间并重新分配大小之间,决定因素是什么?


我不认为下面的代码是最佳的,因为当我重新分配它时,缓冲区

的大小变得非常小。我也花时间

重新分配

吧。然后把这个带到下一步,如果我写一个链表或一个红色黑色

树,我将不得不分配内存。在这种情况下,我如何确定

最佳尺寸?


注意:下面的代码包含一些posix项目。请忽略那些

项目。我也在下面省略了一些错误编码。

下面的

是为了学习正则表达式API而写的。


int

main(无效){


regex_t preg;

char * string = strdup(&hello1hello4hello2hello3你好吗?) ;);

char * match;

regmatch_t pmatch [1];

size_t nmatch = 1;

size_t len = 0;

size_t offset = 0;

int test;


match = calloc(BUFSIZ,sizeof(char ));

if(regcomp(& preg," hello [41]",REG_BASIC)!= 0)

perror(" regcomp failed") ;


while(string [offset]!=''\'''){

test = regexec((const regex_t *)& preg ,& string [offset],

nmatch,pmatch,0);

if(test == REG_NOMATCH || test!= 0){

休息;

}

len = pmatch [0] .rm_eo-pmatch [0] .rm_so;

/ *是这个最佳或我应该使用固定大小的buff呃? * /

match = realloc(match,len + 1);

strlcpy(匹配,& string [offset],

len + 1);

(无效)printf("匹配字符串:%s \ n",匹配);

offset + = pmatch [0] .rm_eo; < br $>

}

(无效)printf("原始字符串:%s \ n",字符串);

免费(匹配);

regfree(& preg);

退出(0);

}

Is it generally better to set-up a buffer (fixed sized array) and read
and write to that
buffer even if it is larger than what is being written to it? Or is it
better to allocate memory and realloc it for the size of the what is
being written each time? In other words, what is the decision factor
between deciding to use a fixed size buffer or allocating memory
space and reallocing the size?

I don''t think the code below is optimal since the size of the "buffer"
becomes extremely small when I realloc it. I also spend time
re-allocating
it. And taking this to the next step, if I wrote to a linked list or a
red black
tree, I would have to allocate memory. In that case, how do I
determine
the best size?

Note: The code below contains some posix items. Please ignore those
items. I have also left out some error coding below as well.
The
below was written to just learn the regex API.

int
main(void) {

regex_t preg;
char *string = strdup("hello1hello4hello2hello3 are you hello");
char *match;
regmatch_t pmatch[1];
size_t nmatch = 1;
size_t len = 0;
size_t offset = 0;
int test;

match = calloc(BUFSIZ, sizeof(char));
if ( regcomp(&preg, "hello[41]", REG_BASIC) != 0)
perror("regcomp failed");

while (string[offset] != ''\0'') {
test = regexec((const regex_t *)&preg, &string[offset],
nmatch, pmatch,0);
if (test == REG_NOMATCH || test !=0) {
break;
}
len = pmatch[0].rm_eo-pmatch[0].rm_so;
/* is this optimal or should I use a fixed sized buffer? */
match = realloc(match, len+1);
strlcpy(match, &string[offset],
len+1);
(void)printf("matched string: %s\n", match);
offset += pmatch[0].rm_eo;

}
(void)printf("original string: %s\n", string);
free(match);
regfree(&preg);
exit(0);
}

推荐答案

bw*****@yahoo.com 写道:
bw*****@yahoo.com wrote:

设置缓冲区(固定大小的数组)并阅读

通常更好并写入

缓冲区,即使它大于写入它的内容?或者它是否更好地分配内存并将其重新分配给每次写入的内容大小?
?换句话说,在决定使用固定大小的缓冲区或分配内存空间并重新分配大小之间,决定因素是什么?
Is it generally better to set-up a buffer (fixed sized array) and read
and write to that
buffer even if it is larger than what is being written to it? Or is it
better to allocate memory and realloc it for the size of the what is
being written each time? In other words, what is the decision factor
between deciding to use a fixed size buffer or allocating memory
space and reallocing the size?



我一般都试图避免大于BUFSIZ的固定缓冲区,我的

认为堆栈限制通常会更多

限制比其他任何东西。 (这不是一个语言问题,但是,b $ b。)对我来说,这更像是一种审美的东西:如果100s

的变量声明在同一个范围很糟糕,然后

声明大数组也不好。


你的代码中有一点奇怪就是缩小尺寸

realloc。一般来说,程序是贪婪的:一旦他们已经获得了记忆,就最容易抓住它。 Malloc

你认为应该处理一般情况的缓冲区

并且如果结果太小则只重新分配。 Realloc

通过加倍大小然后永久保持那个记忆

。如果那是可行的,当然。如果你只是消耗了98%的机器内存来执行一项操作,那么在一个长期运行的程序中,
是10 ^ 276中的1,那么它就是

释放内存是有意义的。这取决于

的情况。


-

Bill Pursell

I generally try to avoid fixed buffers larger than BUFSIZ, my
thinking being that stack limitations will generally be more
restrictive than anything else. (That''s not a language issue,
however.) For me, it''s more of an aesthetic thing: if 100s
of variable declarations in the same scope are bad, then
declaring big arrays is also bad.

One thing that is odd in your code is to downsize with
realloc. Generally, programs are greedy: once they''ve
acquired the memory, it''s easiest to hold onto it. Malloc
a buffer that you think should handle the general case
and only realloc if it turns out to be too small. Realloc
by doubling the size and then hold onto that memory
forever. If that''s feasible, of course. If you just consumed
98% of the machines memory to do an operation that
is a 1 in a 10^276 case in a long-running program, it
makes sense to release the memory. It depends on
the situation.

--
Bill Pursell


bw*****@yahoo.com schrieb:
bw*****@yahoo.com schrieb:

设置缓冲区(固定大小的数组)并读取

并写入

缓冲区通常更好,即使它是大于写入它的内容?或者它是否更好地分配内存并将其重新分配给每次写入的内容大小?
?换句话说,在决定使用固定大小的缓冲区或分配内存空间并重新分配大小之间,决定因素是什么?
Is it generally better to set-up a buffer (fixed sized array) and read
and write to that
buffer even if it is larger than what is being written to it? Or is it
better to allocate memory and realloc it for the size of the what is
being written each time? In other words, what is the decision factor
between deciding to use a fixed size buffer or allocating memory
space and reallocing the size?



如果可以想象你的足够大的话。缓冲区可以是
太小而且如果它对你的程序有害,因为

你抓住了这个案子但是无法处理任何应该是什么

in缓冲区由于尺寸不足,请考虑分配和重新分配内存。


有些系统只有独立的实现,

即缺少< stdlib.h>。在那里,你显然必须使用

固定大小的缓冲区。

If it is conceivable that your "large enough" buffer can be
too small and if it is detrimental for your programme because
you caught this case but cannot handle whatever ought to be
in the buffer because of its lack of size, then consider
allocating and reallocating memory.

There are systems where you only have freestanding implementations,
i.e. lack <stdlib.h>. There, you obviously have to make do with
fixed size buffers.


我不认为下面的代码是最佳的,因为当我重新分配它时,缓冲区

的大小变得非常小。我也花时间

重新分配

吧。然后把这个带到下一步,如果我写一个链表或一个红色黑色

树,我将不得不分配内存。在这种情况下,我如何确定
最佳尺寸?
I don''t think the code below is optimal since the size of the "buffer"
becomes extremely small when I realloc it. I also spend time
re-allocating
it. And taking this to the next step, if I wrote to a linked list or a
red black
tree, I would have to allocate memory. In that case, how do I
determine
the best size?



使用合理的开始大小并选择合理

最小尺寸。

合理取决于你的问题领域和资源

你有你的电话。

理想情况下,分配的缓冲区根本不会调整大小,但确实是

不要求大量的记忆。

不要一直重新分配;如果你在你的程序中遇到malloc()

失败,那么你可以尝试使用
作为回退来将分配的缓冲区调整为最小值和malloc()

再次。


要记住一件事:尝试你的realloc()回退

非常小的初始缓冲区大小和你的错误处理策略

用于非常大的初始缓冲区大小(例如尝试
malloc((size_t)-1))。没有测试,代码不值得任何东西

但是作为善意的表现...

Use a "reasonable" start size and choose a "reasonable"
minimum size.
"Reasonable" depends on your problem domain and the resources
you have at your beck and call.
Ideally, the allocated buffer is never resized at all but does
not claim a substantial amount of your memory.
Do not reallocate all the time; if you run into malloc()
failure somewhere else in your programme, then you could try
as fallback to resize allocated buffers to minimum and malloc()
again.

One thing to keep in mind: Try out your realloc() fallback for
very small initial buffer sizes and your error handling strategies
for very large initial buffer sizes (e.g. try to
malloc((size_t)-1)). Without test, the code is not worth anything
but as a show of goodwill...


注意:下面的代码包含一些posix项目。请忽略那些

项目。我也在下面省略了一些错误编码。

下面的

是为了学习正则表达式API而编写的。
Note: The code below contains some posix items. Please ignore those
items. I have also left out some error coding below as well.
The
below was written to just learn the regex API.



你可能把它们排除在外;提供编译C代码是你获得好答案的最佳选择。


你忘了

#include< stdlib。 h>

#include< stdio.h>

You could have left them out; providing compiling C code is your
best bet for getting good answers.

You forgot to
#include <stdlib.h>
#include <stdio.h>


int

main(void){


regex_t preg;

char * string = strdup(&hello1hello4hello2hello3你好吗?);

char * match;

regmatch_t pmatch [1];

size_t nmatch = 1;

size_t len = 0;

size_t offset = 0 ;

int test;


match = calloc(BUFSIZ,sizeof(char));
int
main(void) {

regex_t preg;
char *string = strdup("hello1hello4hello2hello3 are you hello");
char *match;
regmatch_t pmatch[1];
size_t nmatch = 1;
size_t len = 0;
size_t offset = 0;
int test;

match = calloc(BUFSIZ, sizeof(char));



由于您不知道BUFSIZ的值,您可能会分配

1或1百万字节。

使用固定的初始值。

sizeof(char)总是等于1.如果你想在匹配类型的基础上分配

,那么使用

match = calloc(YOUR_INIT_BUFFER_SIZE,sizeof *匹配);


您也忘了检查calloc()是否成功。这是完全愚蠢的
。不,我不想暗示你是愚蠢的。

但它不会花费你任何证明的东西。你可能会从这里开始上
并且未能证明这可能会导致分段

故障最好和无用的程序失败如果一个重要的

客户和你的老板一起站在你身边

在另一端。

As you do not know the value of BUFSIZ, you might allocate
either 1 or one million bytes.
Go with a fixed initial value.
sizeof (char) always equals 1. If you want to base the allocation
on the type of match, then use
match = calloc(YOUR_INIT_BUFFER_SIZE, sizeof *match);

You also forgot to check whether calloc() succeeded. This is
outright stupid. No, I do not want to imply that you are stupid.
But it does not cost you anything to "prove" that you may go
on from here and failure to prove that may lead to a segmentation
fault at best and ungracious programme failure if an important
customer is standing right beside you together with your boss
on the other end of the scale.


>

if(regcomp(& preg," hello [41]",REG_BASIC)!= 0)

perror(" regcomp failed");


while(string [offset]!=''\'''){

test = regexec((const regex_t *)& preg,& string [offset],

nmatch,pmatch,0);

if(test == REG_NOMATCH || test!= 0){

break ;

}

len = pmatch [0] .rm_eo-pmatch [0] .rm_so;

/ *这是最优还是我应该使用固定大小的缓冲区? * /

match = realloc(match,len + 1);
>
if ( regcomp(&preg, "hello[41]", REG_BASIC) != 0)
perror("regcomp failed");

while (string[offset] != ''\0'') {
test = regexec((const regex_t *)&preg, &string[offset],
nmatch, pmatch,0);
if (test == REG_NOMATCH || test !=0) {
break;
}
len = pmatch[0].rm_eo-pmatch[0].rm_so;
/* is this optimal or should I use a fixed sized buffer? */
match = realloc(match, len+1);



再次,你可以减少分配失败的可能性。

正确的方式是

char * tmp ;

....

tmp = realloc(匹配,len + 1);

if(tmp == 0){

/ *你的错误处理在这里;匹配仍然可用* /

}

match = tmp;


您认为正则表达式函数中没有错误。

这是非常值得信赖的,肯定会尊重那个

库的作者 - 但是,如果len被分配了负值

(其中变成一个大的正值),然后你可能会运行

内存不足或无意中自由(匹配)如果len + 1 == 0.


这是我在上面所说的部分:写一个后备并测试它。

这不是偏执狂但是

- 对你来说是好习惯;从malloc中优雅地恢复()

失败很难
- 可以帮助你捕捉难以捕捉的错误

- 让其他人信任_your_ code - 如果我评估代码

并发现它是malloc()总是成功的变种,

我印象不足。

Once again, you discount the possibility of allocation failure.
The right way is
char *tmp;
....
tmp = realloc(match, len+1);
if (tmp == 0) {
/* Your error handling here; match is still available */
}
match = tmp;

You believe that there is no bug in the regex functions.
This is very trustful and certainly honours the writers of that
library -- however, if len is assigned a negative value
(which becomes a large positive value), then you may run
out of memory or inadvertently free(match) if len+1 == 0.

This is the part I meant above: Write a fallback and test it.
This is no paranoia but
- good practice for you; recovering gracefully from a malloc()
failure is hard
- may help you catch hard-to-catch bugs
- makes other people trust _your_ code -- if I evaluate code
and find it to be of the "malloc() always succeeds variety",
I am less than impressed.


strlcpy(匹配,& string [offset],

len + 1);

(void)printf( 匹配字符串:%s \ n,匹配);

offset + = pmatch [0] .rm_eo;


}

(void)printf("原始字符串:%s \ n",字符串);

免费(匹配);

regfree(& preg) );

退出(0);

}
strlcpy(match, &string[offset],
len+1);
(void)printf("matched string: %s\n", match);
offset += pmatch[0].rm_eo;

}
(void)printf("original string: %s\n", string);
free(match);
regfree(&preg);
exit(0);
}



干杯

迈克尔

-

电子邮件:我的是/ at / gmx / dot / de地址。


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.




感谢您提出的所有好建议。我仍然需要通过

来思考我想要什么?b $ b来处理缓冲。我可以进行绑定检查,并使用256或512的初始

缓冲区。如果字符串的len大于我,那么
只需加倍或更高。我可以在重新分配之前进行检查。

如果字符串不大于,我可以跳过重新分配。


< OT>

我最后的重写只是将它作为

函数移动到我的http服务器中。我想解析和搜索http请求并发送

响应。我使用8196的固定缓冲区缓冲套接字。我想要将查找转储到一个结构中,该结构将成为

链表或红黑的一部分树。我已经开始使用线程,所以

也可能会改变。最大的挑战将是缓冲和

针对URI编写正则表达式。

< / OT>


这是'通过一些错误检查清理代码(缓冲将在第二天或第二天重做
):


#include< sys / types.h>

#include< regex.h>

#include< stdio.h>

#include< stdlib.h>

#include< string.h>

#include< err.h>


int

main(void){


regex_t preg;

char * string = strdup(" hello1hello4hello2hello3 you you hello");

char * match;

char * new_match;

regmatch_t pmatch;

size_t nmatch = 1;

size_t len = 0;

size_t offset = 0;

int test;


match = calloc(BUFSIZ,sizeof(char ));

if(match == NULL)

errx(-1," calloc()无法分配空间!\ n");


if(regcomp(& preg," hello [41]",REG_BASIC)!= 0)

puts(regcomp()无法编译\ n) ;


while(string [offset]!=''\'''){

test = regexec((const regex_t *)& preg ,& string [offset],

nmatch,& pmatch,0);

if(test!= 0){

break ;

}

len = pmatch.rm_eo-pmatch.rm_so;

if((new_match = realloc(match,len + 1)) == NULL){

休息;

}

match = new_match;

strlcpy(匹配,& string [offset],

len + 1);

(void)printf(" matching string:%s \ n",match);

offset + = pmatch.rm_eo;

}

(void)printf(" original string:%s \ n",string);

免费(匹配);

匹配= NULL;

regfree(& preg);

退出(EXIT_SUCCESS) ;

}


Thanks for all the great suggestions. I still need to think through
how I want to
handle the buffering. I can do bound checking and use an initial
buffer of 256 or 512. If the len of the string is larger, than I can
just double up or higher. I can do the check before the reallocation.
If the string is not larger than, I can skip the reallocation.

<OT>
My final re-write will just be moving this into my http server as a
function or two. I want to parse and search http requests and send
responses. I am buffering the sockets with a fixed buffer of 8196. I
want to dump the finds into a structure that will either be part of a
linked list or a red black tree. I have started to use threads, so
that might change as well. The biggest challenge will be buffering and
writing regex against URIs.
</OT>

Here''s the code cleaned up with some error checking (buffering will be
redone over the next day or two):

#include <sys/types.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>

int
main(void) {

regex_t preg;
char *string = strdup("hello1hello4hello2hello3 are you hello");
char *match;
char *new_match;
regmatch_t pmatch;
size_t nmatch = 1;
size_t len = 0;
size_t offset = 0;
int test;

match = calloc(BUFSIZ, sizeof(char));
if (match == NULL)
errx(-1, "calloc() could not allocate space!\n");

if (regcomp(&preg, "hello[41]", REG_BASIC) != 0)
puts("regcomp() failed to compile\n");

while (string[offset] != ''\0'') {
test = regexec((const regex_t *)&preg, &string[offset],
nmatch, &pmatch,0);
if (test !=0) {
break;
}
len = pmatch.rm_eo-pmatch.rm_so;
if ( (new_match = realloc(match, len+1)) == NULL) {
break;
}
match = new_match;
strlcpy(match, &string[offset],
len+1);
(void)printf("matched string: %s\n", match);
offset += pmatch.rm_eo;
}
(void)printf("original string: %s\n", string);
free(match);
match = NULL;
regfree(&preg);
exit(EXIT_SUCCESS);
}


这篇关于缓冲区还是Realloc?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆