且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

这个C风格函数写得好吗,线程安全吗?

更新时间:2023-02-05 22:28:29

9月12日上午10点10分,jeff_j_dun ... @ yahoo.com写道:
On Sep 12, 10:10 am, jeff_j_dun...@yahoo.com wrote:

亲爱的C ++用户:


我alwasy使用std :: string并避免使用char缓冲区但昨晚我想要看看我是否可以制作一个C风格的功能将是线程

安全。


对我来说,这是一个很好的学习经验,因为我的C / C ++知识是

有限但我确实理解由于之前的Delphi

经验导致的线程问题。


在以下函数中,请求假设Date对象很好

写的。我真正想知道的是,如果我的char buff是安全处理的



void fbDateToStr(const IBPP :: Date& d,char * buff)

{

if(d< IBPP :: MinDate || d IBPP :: MaxDate)

{

strcpy(buff,"");

}

else

{

int iMonth = 0,iDay = 0,iYear = 0;

d.GetDate(iYear,iMonth,iDay);

sprintf(buff,"%d /%d / %d,iMonth,iDay,iYear);

}


}


用法:

char buffer [15];

fbDateToStr(dtInitialContactDt,buffer);


退货:

MM / DD / YYYY或如果日期无效,空白字符串


注意:

最初,我想到在函数内创建一个静态缓冲区

而不是像这个函数当前正在做的那样传递一个缓冲区,但这样做会因为缓冲区现在是

而导致线程不安全所有线程都可见/可编辑。
Dear C++ Users:

I alwasy use std::string and avoid char buffers but last night I
wanted to see if I could make a C style function that would be thread
safe.

For me, it was a good learning experience since my C/C++ knowledge is
limited but I do understand threading issues due to prior Delphi
experience.

In the following function, pleas assume that the Date object is well
written. What I really want to know is if my char buff is being
handled safely.

void fbDateToStr( const IBPP::Date &d, char *buff )
{
if ( d < IBPP::MinDate || d IBPP::MaxDate )
{
strcpy(buff, "");
}
else
{
int iMonth=0, iDay=0, iYear=0;
d.GetDate(iYear, iMonth, iDay);
sprintf(buff, "%d/%d/%d", iMonth, iDay, iYear);
}

}

USAGE:
char buffer[15];
fbDateToStr(dtInitialContactDt, buffer);

RETURNS:
MM/DD/YYYY or if date is invalid, a blank string

NOTES:
Initially, I thought of creating a static buffer within the function
instead of passing a buffer as this function currently is doing, but
doing so would have been thread-unsafe since the buffer would now be
visible/editable by all threads.



哦,另外一件我不太明白的事情是,如果我可以将我的缓冲区[10 + 1]改为
完全适应终止角色的MM / DD / YYYY字符串大小

10 + 1?


再次感谢

Oh, and another thing that I don''t really understand is if I can make
my buffer [10+1] to exactly accomodate the MM/DD/YYYY string size of
10 + 1 for the terminating character?

Thanks again


< je *********** @ yahoo.comwrote in message

news:11 ********* *************@g4g2000hsf.googlegro ups.com ...

:亲爱的C ++用户:



:我alwasy使用std :: string并避免使用char缓冲区但昨晚我

:想知道我是否可以创建一个C风格的函数,这将是线程

:安全。



:对我来说,这是一个很好的学习经历,因为我的C / C ++知识是

:有限但是我了解由于之前的Delphi导致的线程问题

:经验。



:在以下函数中,请求假设Date对象很好

:写的。我真正想知道的是,如果我的char buff是

:安全处理。





:void fbDateToStr(const IBPP :: Date& d,char * buff)

:{

:if(d< IBPP :: MinDate || d IBPP) :: MaxDate)

:{

:strcpy(buff,"");

好​​的,或者你可以写:* buff =''\ 0'';


:}

:其他

:{

:int iMonth = 0,iDay = 0,iYear = 0;

:d.GetDate(iYear,iMonth,iDay);

:sprintf(buff," ;%d /%d /%d",iMonth,iDay,iYear);

此调用可能导致意外的缓冲区溢出

如果iYear / iMonth / iDay有超出范围的价值

(例如,如果年份变为12345678而不是2007年)。

您的平台可能会提供一个电话,例如

snprintf或slprintf或sprintf_s,这些都是

,允许限制输出大小更安全。

[你可以n还更安全地依赖于紧身。缓冲区]


另外,如果你想让输出包括领先的

零(01/01/1999),你会想要使用以下内容

格式字符串:"%02d /%02d /%04d"


:}

:}





:用法:

:字符缓冲区[15];

:fbDateToStr (dtInitialContactDt,缓冲区);



:退货:

:MM / DD / YYYY或如果日期无效,则为空白字符串



:注意:

:最初,我想在函数中创建一个静态缓冲区

:而不是传递缓冲区正如此函数当前正在做的那样,但

:这样做本来就是线程不安全的,因为缓冲区现在是

:所有线程可见/可编辑。

确实:确保提供合适大小的缓冲区

是使用C风格字符缓冲区时的关键问题。


处理固定大小的char缓冲区的一些想法i n C ++:


您可以通过引用获取固定大小的char数组:

void fbDateToStr(const IBPP :: Date& d,char(&) buff)[11])

这将检查调用者是否提供了一个

精确所需大小的数组。


你也可以将一个封装为

的字符数组返回到结构中。例如,使用类似

boost :: array:

array< char,11fbDateAsStr(IBPP :: Date const& d)

{

数组< char,11ans;

...

返回ans;

}

hth-Ivan

-
http://ivan.vecerina.com/contact/?subject=NG_POST < - 电子邮件联系表格

Brainbench MVP for C ++< http://www.brainbench.com

<je***********@yahoo.comwrote in message
news:11**********************@g4g2000hsf.googlegro ups.com...
: Dear C++ Users:
:
: I alwasy use std::string and avoid char buffers but last night I
: wanted to see if I could make a C style function that would be thread
: safe.
:
: For me, it was a good learning experience since my C/C++ knowledge is
: limited but I do understand threading issues due to prior Delphi
: experience.
:
: In the following function, pleas assume that the Date object is well
: written. What I really want to know is if my char buff is being
: handled safely.
:
:
: void fbDateToStr( const IBPP::Date &d, char *buff )
: {
: if ( d < IBPP::MinDate || d IBPP::MaxDate )
: {
: strcpy(buff, "");
Ok, or you could just write: *buff = ''\0'';

: }
: else
: {
: int iMonth=0, iDay=0, iYear=0;
: d.GetDate(iYear, iMonth, iDay);
: sprintf(buff, "%d/%d/%d", iMonth, iDay, iYear);
This call could cause an unexpected buffer overfow
if iYear/iMonth/iDay has an out-of-range value
(e.g. if year somehow gets to be 12345678 instead of 2007).
Your platform probably provides a call such as
snprintf or slprintf or sprintf_s, which are
all safer by allowing to restrict output size.
[ you can then also more safely rely on a "tight fit" buffer ]

Also, if you want the output to include leading
zeroes (01/01/1999), you''ll want to use the following
format string: "%02d/%02d/%04d"

: }
: }
:
:
: USAGE:
: char buffer[15];
: fbDateToStr(dtInitialContactDt, buffer);
:
: RETURNS:
: MM/DD/YYYY or if date is invalid, a blank string
:
: NOTES:
: Initially, I thought of creating a static buffer within the function
: instead of passing a buffer as this function currently is doing, but
: doing so would have been thread-unsafe since the buffer would now be
: visible/editable by all threads.
Indeed: making sure that a buffer of the right size is provided
is a key issue when using C-style character buffers.

Some ideas for dealing with fixed-size char buffers in C++:

You can take a fixed size char array by reference:
void fbDateToStr( const IBPP::Date &d, char (&buff)[11] )
This will check that the caller provides an array of the
exact desired size.

You could also return a character array encapsulated
into a struct. For instance, using something like
boost::array:
array<char,11fbDateAsStr( IBPP::Date const& d )
{
array<char,11ans;
...
return ans;
}
hth-Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <http://www.brainbench.com


9月12日下午4:15,jeff_j_dun ... @ yahoo.com写道:
On Sep 12, 4:15 pm, jeff_j_dun...@yahoo.com wrote:

9月12日上午10点10分,jeff_j_dun ... @ yahoo.com写道:
On Sep 12, 10:10 am, jeff_j_dun...@yahoo.com wrote:

>>

对我来说,这是一次很好的学习经历,因为我的C / C ++知识是

有限,但我确实理解由于之前的Delphi

经验导致的线程问题。
>>
For me, it was a good learning experience since my C/C++ knowledge is
limited but I do understand threading issues due to prior Delphi
experience.


在以下函数中,请求假设Date对象很好地写了
。我真正想知道的是,如果我的char buff是安全处理的

In the following function, pleas assume that the Date object is well
written. What I really want to know is if my char buff is being
handled safely.


void fbDateToStr(const IBPP :: Date& d,char * buff)

{

if(d< IBPP :: MinDate || d IBPP :: MaxDate)

{

strcpy(buff,"");

}

其他

{

int iMonth = 0,iDay = 0,iYear = 0;

d.GetDate(iYear,iMonth,iDay);

sprintf(buff,"%d /%d /%d",iMonth,iDay,iYear);

}
void fbDateToStr( const IBPP::Date &d, char *buff )
{
if ( d < IBPP::MinDate || d IBPP::MaxDate )
{
strcpy(buff, "");
}
else
{
int iMonth=0, iDay=0, iYear=0;
d.GetDate(iYear, iMonth, iDay);
sprintf(buff, "%d/%d/%d", iMonth, iDay, iYear);
}


}
}


用法:

char buffer [15];

fbDateToStr(dtInitialContactDt,buffer);
USAGE:
char buffer[15];
fbDateToStr(dtInitialContactDt, buffer);



如果缓冲区是堆栈分配而不是线程本地

并且其他线程无法访问,那么

不是并发问题。


你的日期写得好吗?


如果线程怎么办? enteres else阻止并且

然后在调用GetDate之前被抢占,

然后另一个线程改变d以便


d< IBPP :: MinDate || d IBPP :: MaxDate


GetDate初始化iMonth等的值是什么......?


通过const引用传递d只意味着

你不能在fbDateToStr中调用Date

的非常量成员。它并不意味着它可以不被其他线程改变。

If buffer is stack allocated than it is thread local
and can not be accessed by other threads, so there
are no concurrency issues.

What do you mean that Date is well written?

what if the thread enteres else block and is
then preempted before GetDate is called,
and another thread then changes d so that

d < IBPP::MinDate || d IBPP::MaxDate

what values will GetDate initialize iMonth, etc...?

passing d by const reference only means that
you can not call non const members of Date
within fbDateToStr. It doesn''t mean that it can
not be changed by some other thread.


RETURNS :

MM / DD / YYYY或者如果日期无效,空白字符串
RETURNS:
MM/DD/YYYY or if date is invalid, a blank string


注意:

最初,我想在函数

中创建一个静态缓冲区,而不是像这个函数当前正在做的那样传递缓冲区,但

这样做就是线程-unsafe,因为所有线程的缓冲区现在都是可见/可编辑的。
NOTES:
Initially, I thought of creating a static buffer within the function
instead of passing a buffer as this function currently is doing, but
doing so would have been thread-unsafe since the buffer would now be
visible/editable by all threads.



哦,还有一件我不太明白的事情是,如果我可以将我的缓冲区[10 + 1]改为
正好适应终止角色的MM / DD / YYYY字符串大小

10 + 1?


Oh, and another thing that I don''t really understand is if I can make
my buffer [10+1] to exactly accomodate the MM/DD/YYYY string size of
10 + 1 for the terminating character?



如果你确定这个月和一天不能超过99

并且年份不能大于9999那么你需要

最多11个字符的缓冲区。


DS

If you are sure that month and day can not be greater than 99
and that the year can not be greater than 9999 then you need
at most 11 character buffer.

DS