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

时间:2014-09-07 01:37:48

标签: c arrays malloc strlen

我目前正在制作一个涉及为考​​试创建模板的计划。 在我允许用户向考试添加问题的功能中,我需要确保仅使用存储其数据所需的内存。经过对各种输入函数(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而不是印象,这样做会删除终止字符之前的任何内容(换行符,正确吗?)。不过,它在不同的行上显示了所有内容。 所以现在我有些困惑,并怀疑我对字符数组如何工作的了解。任何人都可以帮助清理这里发生的事情,或者为我提供一个能够更详细地解释这一切的资源吗?

2 个答案:

答案 0 :(得分:6)

在C中,字符串通常以空值终止。但是,Strlen仅计算null之前的字符。因此,您必须在strlen的值中添加一个以获得足够的空间。或致电strdup

答案 1 :(得分:1)

C字符串包含您可以看到的字符" abc"加一个你可以标记字符串结尾的标记。您将此表示为' \ 0'。 strlen函数使用' \ 0'找到字符串的结尾,但不计算它。

所以

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

是对的。但是,你尝试了什么:

myvar = malloc(strlen(str));

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

虽然INCORRECT, MAY 似乎在某些时候有效。这是因为malloc通常以块的形式分配内存(比如可能以16字节为单位),而不是您要求的确切大小。所以有时候,你可能会“幸运”。并最终使用' slop'在大块的末尾。