c-为什么在为字符数组的strlen分配空间时加1



我目前正在开发一个程序,该程序涉及为考试创建模板。在允许用户向考试添加问题的功能中,我需要确保我只使用存储数据所需的内存。在对各种输入函数(getc、scanf等)之间的差异进行了大量研究后,我成功地做到了这一点,我的程序似乎正在运行,但我担心一件事。这是我的函数代码,我在有问题的行上加了一条注释:

int AddQuestion(){
Question* newQ = NULL;
char tempQuestion[500];
char* newQuestion;
if(exam.phead == NULL){
    exam.phead = (Question*)malloc(sizeof(Question));
}
else{
    newQ = (Question*)malloc(sizeof(Question));
    newQ->pNext = exam.phead;
    exam.phead = newQ;
}
while(getchar() != 'n');
puts("Add a new question.n"
     "Please enter the question text below:");
fgets(tempQuestion, 500, stdin);
newQuestion = (char*)malloc(strlen(tempQuestion) + 1); /*Here is where I get confused*/
strcpy(newQuestion, tempQuestion);
fputs(newQuestion, stdout);
puts("Done!");
return 0;
}

让我困惑的是,我曾尝试运行相同的代码,但进行了一些小的更改,以测试幕后到底发生了什么。我试着从我的malloc中删除+1,我把它放在那里是因为strlen只计数到但不包括终止字符,我认为我希望包括终止字符。这仍然顺利进行。所以我试着运行它,但使用-1,因为这样做会删除终止字符(换行符,对吗?)之前的内容。尽管如此,它还是在单独的行中显示了所有内容。所以现在我有点困惑和怀疑我对字符数组如何工作的了解。有人能帮我澄清一下这里发生了什么吗,或者也许能为我提供一个资源,更详细地解释这一切吗?

在C中,字符串通常以null结尾。然而,Strlen只计算null之前的字符。因此,您总是必须在strlen的值上加一才能获得足够的空间。或致电strdup

一个C字符串包含你能看到的字符"abc"加上一个你看不到的字符,这标志着字符串的结束。您将其表示为"\0"。strlen函数使用"\0"来查找字符串的末尾,但不计算。

所以

myvar = malloc(strlen(str) + 1);

是正确的。然而,你尝试的是:

myvar = malloc(strlen(str));

myvar = malloc(strlen(str) - 1);

虽然不正确,但可能在某些时候起作用。这是因为malloc通常以块为单位分配内存(比如说,可能以16字节为单位),而不是您要求的确切大小。因此,有时,你可能会"运气好",最终在块的末尾使用"slop"。

C字符串以空字符''结尾。当对字符串调用strlen时,它只计算字符数,直到到达null终止符为止(它本身不计算null终止符)。

例如,如果你这样做:

const char *example = "Hello!";
char *s = calloc(strlen(example), sizeof(char));
printf("%sn", s);

然后将分配字符串s(它在内存中看起来像这样):

'H', 'e', 'l', 'l', 'o', '!'

但是C字符串需要以null结尾,所以我们分配了为null结尾符''保留的额外字节。

相关内容

  • 没有找到相关文章