C语言 为字符串分配空间然后将字符插入该空间的正确方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5614411/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:21:43  来源:igfitidea点击:

Correct way to malloc space for a string and then insert characters into that space?

c

提问by Kelp

I have two strings, str1 and str2. I want the concatenation of them on a space in the heap. I malloc space for them using:

我有两个字符串,str1 和 str2。我希望将它们连接到堆中的一个空间中。我使用以下方法为他们分配空间:

char *concat = (char*) malloc(strlen(str1) + strlen(str2) + 1);

Can I just do:

我可以这样做吗:

strcat(concat, str1);
strcat(concat, str2);

And concat will give me the place on the heap with the two strings concatted? I am asking because it seems that strcat would actually add the str1 to the end of the space allocated using malloc. Is this correct? So, then, str1 would appear at position strlen(str1) + strlen(str2) + 1.

并且 concat 会给我在两个字符串连接的堆上的位置?我问是因为似乎 strcat 实际上会将 str1 添加到使用 malloc 分配的空间的末尾。这样对吗?那么,str1 将出现在位置 strlen(str1) + strlen(str2) + 1。

The reason that I am asking is that I am using the method above, but I am getting an error in valgrind: Conditional jump or move depends on uninitialised value(s)

我问的原因是我正在使用上面的方法,但我在 valgrind 中遇到错误:条件跳转或移动取决于未初始化的值

回答by Walter Mundt

What strcat(dest, src)actually does is search for the a null byte starting at destand going forward, and then write the srcstring there.

什么strcat(dest, src)实际上做的是搜索一个空字节开始dest和前进,然后写入src字符串出现。

After malloc, the contents of memory are undefined, so your current code could do any number of things, most of them incorrect. If you do concat[0] = 0before the strcat's, then your code works but will have to search for the length of str1three times -- once for strlen, again for the first strcat, and last for the second strcat.

之后malloc,内存的内容是未定义的,所以你当前的代码可以做很多事情,其中​​大部分是不正确的。如果您concat[0] = 0strcat's之前这样做,那么您的代码可以工作,但必须搜索str1三遍的长度- 一次为strlen,再次为第一次strcat,最后为第二次strcat

Instead though, I recommend using memcpy:

相反,我建议使用 memcpy:

size_t len1 = strlen(str1), len2 = strlen(str2);
char *concat = (char*) malloc(len1 + len2 + 1);

memcpy(concat, str1, len1);
memcpy(concat+len1, str2, len2+1);

This takes advantage of the fact that you know from the start where you want the bytes of both strings to go, and how many there are.

这利用了这样一个事实,即您从一开始就知道两个字符串的字节要去哪里,以及有多少。

回答by Chris Eberle

You want to do a strcpy and then a strcat:

你想做一个 strcpy 然后一个 strcat:

strcpy(concat, str1);
strcat(concat, str2);

strcat relies on there being a null terminator ('\0') to know where to begin. If you just malloc and strcat, it's going to do some nasty things.

strcat 依赖于空终止符 ('\0') 来知道从哪里开始。如果你只是 malloc 和 strcat,它会做一些讨厌的事情。

And no, neither strcpy nor strcat will do any kind of implicit allocation or reallocation.

不, strcpy 和 strcat 都不会进行任何类型的隐式分配或重新分配。

回答by Tim Cooper

I would personally do the following:

我个人会做以下事情:

size_t length = strlen(str1) + strlen(str2) + 1;
char *concat = malloc(sizeof(char) * length);

if(concat == NULL)
{
    // error
}

snprintf(concat, length, "%s%s", str1, str2);