英文:
Is there a function(s) to copy a string into a new space in memory
问题
如果我想在C编程中将字符串`"Best School"`复制到内存中的新空间,我可以使用哪些语句来为它保留足够的空间?
我已经尝试过以下两种方式:
malloc(strlen("Best School") + 1)
以及
malloc(sizeof("Best School"))
英文:
If I want to copy the string "Best School"
into a new space in memory in C programming, What statement(s) can I use to reserve enough space for it?
I have tried using this:
malloc(strlen("Best School") + 1)
And this also
malloc(sizeof("Best School"))
答案1
得分: 3
最简单和最安全的分配一块内存并将以null结尾的字符串复制到其中的方法是:
char *ptr = strdup("Best School");
strdup()
在<string.h>
中声明,自从其创立以来一直是POSIX标准的一部分,并且最终在C23标准中成为了标准C的一部分。它在大多数系统上都可用,并且可以这样定义:
#include <stdlib.h>
char *strdup(const char *s) {
size_t size = strlen(s) + 1;
char *p = malloc(size);
return p ? memcpy(p, s, size) : NULL;
}
或者,您可以直接使用malloc
,strlen
和strcpy
:
malloc
分配给定大小的内存块。内存未初始化,其内容是不确定的,因此如果分配成功,您必须将字符串复制到其中,包括空终止符('\0'
)。"Best school"
是一个以null结尾的字符串,有12个字节:11个字符加上一个null终止符字节。
// 为null终止符添加1
char *ptr = malloc(strlen("Best school") + 1);
if (ptr) strcpy(ptr, "Best school");
对于字符串字面量,甚至可以使用sizeof
:
// sizeof包括字符串字面量中的null终止符
char *ptr = malloc(sizeof "Best school");
if (ptr) strcpy(ptr, "Best school");
但上述两种解决方案都容易出错,因为:
- 容易忘记为null终止符分配或复制额外的字节。这个错误会导致未定义的行为,但由于分配的粒度,可能在一段时间内不会被检测到:例如,为
"Best school"
分配11个字节可能返回一个16字节的块,第12个字节可能恰好是null字节,特别是如果此内存以前未被使用。这种未定义的行为是隐匿的,会在最糟糕的时候出现问题。 sizeof
版本**仅适用于字符串字面量!**如果要分配指向的字符串的副本,sizeof(ptr)
将评估为指针的大小,而不是字符串的大小,对于除最短字符串以外的所有字符串都会导致未定义的行为。这个解决方案适用于问题中的示例,但应该被忽略。
推荐的解决方案是使用strdup
。
英文:
The simplest and safest way to allocate a block of memory and copy a null terminated string into it is:
char *ptr = strdup("Best School");
strdup()
is declared in <string.h>
, has been part of the POSIX Standard since its inception and finally made it into Standard C as of C23. It is available on most systems and can be defined this way:
#include <stdlib.h>
char *strdup(const char *s) {
size_t size = strlen(s) + 1;
char *p = malloc(size);
return p ? memcpy(p, s, size) : NULL;
}
Alternately, you could use malloc
, strlen
and strcpy
directly:
malloc
allocates a block memory of a given size. The memory is uninitialized, its contents are indeterminate, so if the allocation was successful, you must then copy the string into it, including the null terminator ('\0'
). "Best school"
is a null terminated string with 12 bytes: 11 characters plus a null terminator byte.
// add 1 for the null terminator
char *ptr = malloc(strlen("Best school") + 1);
if (ptr) strcpy(ptr, "Best school");
And for string literals, you could even use sizeof
:
// sizeof includes the null terminator in a string literal
char *ptr = malloc(sizeof "Best school");
if (ptr) strcpy(ptr, "Best school");
But both of the above solutions are error prone because:
- one can easily forget to allocate or copy the extra byte for the null terminator. This bug causes undefined behavior, but can go undetected for some time because of the allocation granularity: e.g. allocating 11 bytes for
"Best school"
may return a block of 16 bytes and the 12th byte may happen to be a null byte, especially if this memory has not been used before. This kind of undefined behavior is sly and will bite at the worst time. - the
sizeof
version only works for string literals! If you want to allocate a copy of a string you only have a pointer to,sizeof(ptr)
will evaluate to the size of the pointer, not that of the string, leading to undefined behavior for all but the shortest strings. This solution works for the example in the question, but should be disregarded.
The recommended solution is strdup
.
答案2
得分: 0
你需要分配内存并复制原始字符串。我建议一开始(出于教育目的)编写所有函数。以下是示例:
size_t mystrlen(const char *str)
{
char *end = str;
if(str) while(*end) end++;
return end - str;
}
void *mymemcpy(void *dest, const void *src, size_t len)
{
if(dest && src)
{
const unsigned char *ucsrc = src;
unsigned char *ucdest = dest;
while(len--) *ucdest++ = *ucsrc++;
}
return dest;
}
char *mystrdup(const char *str)
{
char *newstr = NULL;
size_t len = 0;
if(str)
{
len = mystrlen(str) + 1;
newstr = malloc(len);
if(newstr)
{
mymemcpy(newstr, str, len);
}
}
return newstr;
}
英文:
You need to allocate the memory and copy the original string. I would advice at the beginning (for educational purposes) to write all functions. Here is an example
size_t mystrlen(const char *str)
{
char *end = str;
if(str) while(*end) end++;
return end - str;
}
void *mymemcpy(void *dest, const void *src, size_t len)
{
if(dest && src)
{
const unsigned char *ucsrc = src;
unsigned char *ucdest = dest;
while(len--) *ucdest++ = *ucsrc++;
}
return dest;
}
char *mystrdup(const char *str)
{
char *newstr = NULL;
size_t len = 0;
if(str)
{
len = mystrlen(str) + 1;
newstr = malloc(len);
if(newstr)
{
mymmemcpy(newstr, str, len);
}
}
return newstr;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论