C 函数从字符串复制到已分配内存时出错
对于下面的C字谜问题,我有一些新的想法。我很好奇更多的C程序员会怎么想。。。请查看示例代码:C 函数从字符串复制到已分配内存时出错,c,memcpy,strlen,calloc,C,Memcpy,Strlen,Calloc,对于下面的C字谜问题,我有一些新的想法。我很好奇更多的C程序员会怎么想。。。请查看示例代码: char * strdup (const char * s) { char * buf; int len; assert(s != NULL); len = strlen(s); buf = (char *) calloc(len + 1, sizeof(char)); memcpy(buf, s, len); return buf; }
char * strdup (const char * s) {
char * buf;
int len;
assert(s != NULL);
len = strlen(s);
buf = (char *) calloc(len + 1, sizeof(char));
memcpy(buf, s, len);
return buf;
}
上面建议的strdup()实现包含一个运行时错误,该错误可能不会在每次调用时一致出现。以下哪项准确描述了此错误
这一问题的可能答案是:
1 calloc()的参数不会导致分配足够的内存来存储s的内容
2如果内存不足,calloc()可能会失败并返回NULL。该代码没有预料到这种情况
3 memcpy()如果用于复制ASCII字符串,可能会损坏数据
4 buf从不以NUL结尾,因此不能由影响字符串的C库函数使用
5该函数返回指向动态内存的指针。应避免这种做法,并始终构成内存泄漏
我认为正确答案是2,但更多的是因为其他答案对我来说似乎不正确,而不是因为答案2是直接正确的答案
- 答案1似乎不正确,因为calloc保留了足够的内存(len+1)来适当结束字符串
- 我不知道答案3写了什么
- 回答4:memcpy将s的内容复制到buf,最后一个字节等于0(复制len字节,注意previos对calloc的调用将最后一个字节填充为0)。所以这个答案是不正确的,
- 答复5:
提前感谢…正确答案是2和5
#2
,因为内存分配函数可能会失败,您必须检查它们的返回值
#5
因为,除非记录函数动态分配返回缓冲区的事实,否则调用者无法知道必须释放返回缓冲区
#1
是不正确的,因为正如您正确地说的calloc
分配字符串所需的内存+为NULL
终止所需的额外字节
#3
不正确,因为它不正确,memcpy
只是将数据从源复制到目标。它不受内存中存储内容的影响
#4
不正确,因为calloc
会将分配的内存归零。我的答案也是2。因为calloc
在失败时会返回NULL,您永远不应该使用NULL指针调用memcpy
。1和4完全不正确。不知道3“memcpy()如果用于复制ASCII字符串,可能会损坏数据”是什么意思。5可能是有争议的,但是在C中没有太多的选择!strlen返回一个size\u t,但len是int?顺便说一句,为什么不使用strcpy?我认为5不正确,只是因为“总是”这个词。@lerosQ:我认为它是正确的,因为除非您的接口文档说明了动态内存分配,否则这样做“总是”不正确。由于没有提到文件,我认为这是一个有效的声明。是的,#5中的措辞听起来像是你应该始终避免动态内存分配。@MrLister:除非你告诉用户你的函数,或者更好的选择是让用户预先分配缓冲区并将其作为参数传递。如果你有自由设计自己的接口,第二个选择总是更好。在我的书中,如果你有一个“除非”,那么就没有“总是”的位置。但无论如何,这种做法应该避免。