为特定的“字符串”分配内存

3

我刚开始学习C语言中的内存管理,但是有些地方不明白。我想要分配12个字节大小的缓冲区,也就是 Hello World!字符串的确切大小(不包含结束符号)。

然后我想用 strcat 函数将一个字符串附加到当前字符串末尾,但是由于会出现 core dumped 错误,所以我不能这样做。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    char mystr[12] = "Hello World!";
    # allocate memory to mystr?
    char *ptr = (char*) malloc(13 * sizeof(char));
    
    strcat(mystr, "Hello");
    return 0;
}

因此,如果malloc除了目标大小之外没有其他参数,我不知道如何为mystr变量分配内存。

2
12字节。这是“Hello World!”的确切大小。这恰好比容纳“Hello World!”短1个字节。 - Gerhardh
3
在静态分配 mystr 后,您无法调整其大小。 - Inian
@Gerhardh 所以这就是我想做的,将另外5个字节添加到缓冲区,然后我就可以strcat另一个字符串了。 - ArlichBachman
2
mystr与动态内存管理没有任何关系。您不会在mystr上使用malloc等函数。 - Gerhardh
@WeatherVane 同意,当发生这种情况时总是令人困惑。 - Acorn
显示剩余8条评论
3个回答

3

如果malloc除了目标大小之外没有其他参数,那么我该如何为mystr变量分配内存,这一点我并不知道。

无法为数组分配额外的内存。相反,您需要分配一个新的内存块,并将原始字符串复制到该内存的开头(strcpy),然后附加剩余部分(strcat):

char *p = (char*) malloc((12 + 5 + 1) * sizeof(char));

strcpy(p, myptr);
strcat(p, "Hello");

第一个字符串为12,第二个字符串为5,再加上一个空字符。

当然,由于您知道最终的大小,您也可以简单地分配一个足够大的数组,而不是使用malloc(您也可以使用memcpy)。


如果您不知道要分配多少,该怎么办? - 0___________
你不需要“分配”足够大的数组,只需要定义它即可。 - 0___________
1
@P__J__ 回答不应该试图通过涵盖每一个可能的情况来取代 C 书籍。 - Acorn
@P__J__ 这是一个堆栈分配,虽然在法律术语中我们不会这样称呼它。 - Acorn
但是应该回答问题,而这个并没有。你也可以声明它为char *mystr[4*1024*1024],这个字符串足以容纳1200页的书。 - 0___________

0
问题应该是C语言中的字符串总是以NULL字符结尾(也称为'\0'),因此您的字符串实际上有13个字符长。(该字符始终会自动添加到字符串文字中,并用于告知字符串停止的位置,因为字符串没有固定长度。)
因此,strcat尝试读取字符串Hello world!后面跟着垃圾(因为未包括空终止符)。
P.S.:错误不是core dumped,而是在其之前的Segmentation fault,这告诉您正在尝试更改不应更改的段中的内容(或执行/读取不应执行/读取的内容--这是一项安全功能)。
编辑:修改字符串mystr后,您还需要更改分配的长度(在malloc中:使用13 * sizeof(char),或者在这种情况下更简单地使用sizeof(mystr))。
P.S. 2:在C中,注释也是以//开头,而不是#(那些是预处理器指令)。

主要问题不在于字符串的缓冲区大小,而是我不知道已经声明的字符串的缓冲区大小是无法更改的。无论如何,谢谢。 - ArlichBachman
这并不完全正确。原始问题定义了char mystr[12] = "Hello World!";,它存储了12个字符但没有空终止符。这是完全合法的,只是该数组不是一个“字符串”。 - Weather Vane

0

你不能改变数组的大小。 mystr 也必须是动态分配的。

int main(int argc, char const *argv[])
{
    const char *ptr = "Hello World!";
    const char *ptr2 = "hello";
    char *mystr = malloc(strlen(ptr)+1);

    strcpy(mystr, ptr);
    mystr = realloc(mystr, strlen(mystr) + strlen(ptr2) + 1);
    strcat(mystr, ptr2);
    return 0;
}

1
@Gerhardh 如果 malloc 没有检查结果也不好。但这次我故意牺牲了正确性。 - 0___________
@Gerhardh 谢谢你告诉我!我会没事的,谢谢家人。在此之前,我需要先学习一下什么是 const(分号)。 - ArlichBachman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接