strdup() - 它在 C 中做什么?
C 中的 strdup()
函数的用途是什么?
What is the purpose of the strdup()
function in C?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
C 中的 strdup()
函数的用途是什么?
What is the purpose of the strdup()
function in C?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(11)
正如它听起来的那样,假设您习惯了 C 和 UNIX 分配单词的缩写方式,它重复字符串 :-)
请记住,它实际上不是一部分当前 (C17) ISO C 标准本身(a)(这是 POSIX 的事情),它实际上与以下代码执行相同的操作:
换句话说:
它尝试分配足够的内存保存旧字符串(加上“\0”字符来标记字符串的结尾)。
如果分配失败,则会将
errno
设置为ENOMEM
并立即返回NULL
。 将errno
设置为ENOMEM
是malloc
在 POSIX 中执行的操作,因此我们不需要在strdup
中显式执行此操作代码>. 如果您不符合 POSIX 标准,ISO C 实际上并不强制要求ENOMEM
的存在,因此我没有将其包含在此处(b).否则分配成功,因此我们将旧字符串复制到新字符串(c)并返回新地址(调用者负责在某个时刻释放该地址)。
请记住这是概念定义。 任何值得薪水的库编写者都可能提供针对正在使用的特定处理器的高度优化的代码。
另一件需要记住的事情是,根据草案
N2912,此目前预计将与
。strndup
一起纳入标准的 C2x 迭代中文档的(a) 但是,以
str
和小写字母开头的函数由标准保留以供将来使用。 来自C11 7.1.3 保留标识符
:string.h 的未来方向 可以在
C11 7.31.13 字符串处理
中找到:因此,如果您想安全的话,您可能应该将其称为其他名称。
(b) 更改基本上是将
if (d == NULL) return NULL;
替换为:(c) 请注意,我使用 < code>strcpy 因为这清楚地表明了意图。 在某些实现中,使用 memcpy 可能会更快(因为您已经知道长度),因为它们可能允许以更大的块或并行方式传输数据。 或者它可能不会:-) 优化口头禅#1:“测量,不要猜测”。
无论如何,如果您决定走那条路,您会这样做:
Exactly what it sounds like, assuming you're used to the abbreviated way in which C and UNIX assigns words, it duplicates strings :-)
Keeping in mind it's actually not part of the current (C17) ISO C standard itself(a) (it's a POSIX thing), it's effectively doing the same as the following code:
In other words:
It tries to allocate enough memory to hold the old string (plus a '\0' character to mark the end of the string).
If the allocation failed, it sets
errno
toENOMEM
and returnsNULL
immediately. Setting oferrno
toENOMEM
is somethingmalloc
does in POSIX so we don't need to explicitly do it in ourstrdup
. If you're not POSIX compliant, ISO C doesn't actually mandate the existence ofENOMEM
so I haven't included that here(b).Otherwise the allocation worked so we copy the old string to the new string(c) and return the new address (which the caller is responsible for freeing at some point).
Keep in mind that's the conceptual definition. Any library writer worth their salary may have provided heavily optimised code targeting the particular processor being used.
One other thing to keep in mind, it looks like this is currently slated to be in the C2x iteration of the standard, along with
strndup
, as per draftN2912
of the document.(a) However, functions starting with
str
and a lower case letter are reserved by the standard for future directions. FromC11 7.1.3 Reserved identifiers
:The future directions for
string.h
can be found inC11 7.31.13 String handling <string.h>
:So you should probably call it something else if you want to be safe.
(b) The change would basically be replacing
if (d == NULL) return NULL;
with:(c) Note that I use
strcpy
for that since that clearly shows the intent. In some implementations, it may be faster (since you already know the length) to usememcpy
, as they may allow for transferring the data in larger chunks, or in parallel. Or it may not :-) Optimisation mantra #1: "measure, don't guess".In any case, should you decide to go that route, you would do something like:
也许代码比使用
strcpy()
快一点,因为\0
字符不需要再次搜索(它已经使用strlen() 搜索过) )。
编辑:根据一些文档,当分配失败时,
strdup()
将errno
设置为ENOMEM
。Maybe the code is a bit faster than with
strcpy()
as the\0
char doesn't need to be searched again (It already was withstrlen()
).EDIT: according to some documents,
strdup()
setserrno
toENOMEM
when allocation fails.没有必要重复其他答案,但请注意,从 C 角度来看,strdup() 可以做任何它想做的事情,因为它不属于任何 C 标准。 然而它是由 POSIX.1-2001 定义的。
No point repeating the other answers, but please note that
strdup()
can do anything it wants from a C perspective, since it is not part of any C standard. It is however defined by POSIX.1-2001.来自strdup man:
strdup()
函数应返回一个指向新字符串的指针,该字符串是s1
指向的字符串的副本。 返回的指针可以传递给free()
。 如果无法创建新字符串,则返回空指针。From strdup man:
The
strdup()
function shall return a pointer to a new string, which is a duplicate of the string pointed to bys1
. The returned pointer can be passed tofree()
. A null pointer is returned if the new string cannot be created.strdup() 对包含结束字符 '\0' 的字符数组进行动态内存分配,并返回堆内存的地址:
因此,它所做的是为我们提供另一个与其参数给出的字符串相同的字符串,而不需要我们来分配内存。 但稍后我们仍然需要释放它。
strdup() does dynamic memory allocation for the character array including the end character '\0' and returns the address of the heap memory:
So, what it does is give us another string identical to the string given by its argument, without requiring us to allocate memory. But we still need to free it, later.
strdup
和strndup
在 POSIX 兼容系统中定义为:strdup() 函数 为
string
str
,进行复制,并返回指向它的指针。该指针随后可以用作函数
free
的参数。如果可用内存不足,则返回 NULL 并将 errno 设置为
ENOMEM
。strndup() 函数从字符串
str
中复制最多len
个字符,始终以 null 终止复制的字符串。strdup
andstrndup
are defined in POSIX compliant systems as:The strdup() function allocates sufficient memory for a copy of the
string
str
, does the copy, and returns a pointer to it.The pointer may subsequently be used as an argument to the function
free
.If insufficient memory is available,
NULL
is returned anderrno
is set toENOMEM
.The strndup() function copies at most
len
characters from the stringstr
always null terminating the copied string.它通过运行传入字符串的 malloc 和 strcpy 来复制传入的字符串。malloc 的缓冲区将返回给调用者,因此需要对返回值运行免费。
It makes a duplicate copy of the string passed in by running a malloc and strcpy of the string passed in. The malloc'ed buffer is returned to the caller, hence the need to run free on the return value.
语句:
相当于(除了改变指针这一事实之外):
而:
相当于:
因此,如果您希望复制的字符串在另一个函数中使用(因为它是在堆部分中创建的),你可以使用
strdup
,否则strcpy
就足够了,The statement:
is equivalent to (other than the fact this changes the pointers):
Whereas:
is equivalent to:
So, if you want the string which you have copied to be used in another function (as it is created in heap section), you can use
strdup
, elsestrcpy
is enough,它所做的最有价值的事情是为您提供另一个与第一个字符串相同的字符串,而不需要您自己分配内存(位置和大小)。 但是,如上所述,您仍然需要释放它(但这也不需要数量计算。)
The most valuable thing it does is give you another string identical to the first, without requiring you to allocate memory (location and size) yourself. But, as noted, you still need to free it (but which doesn't require a quantity calculation, either.)
strdup()函数是字符串重复的简写,它接收一个字符串常量或字符串文字参数,并为字符串分配足够的空间,并在分配的空间中写入相应的字符,最后返回分配的地址调用例程的空间。
The strdup() function is a shorthand for string duplicate, it takes in a parameter as a string constant or a string literal and allocates just enough space for the string and writes the corresponding characters in the space allocated and finally returns the address of the allocated space to the calling routine.
使用 strdup 您可以获得字符串 word 或任何字符串的可修改副本。 这样,您就可以更改其内容,而不会遇到更换硬盘的问题。
Using strdup you can get a modifiable copy of the string word or any string. In this way, you can change its contents without encountering the problems of replacing the hard memory.