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