来自面试的C问题

时间:2011-02-17 20:09:56

标签: c

在这些代码失败的哪些行中(意思是:不做他们应该做的事情),为什么?

int main(void) {
 char student[64] = "some guy";
 char* teacher;

 /* line1 */ strcpy(teacher, student);
 /* line2 */ teacher=student;
 /* line3 */ strcpy(student, "Alber Einstein");
 /* line4 */ student = teacher;
}

6 个答案:

答案 0 :(得分:8)

第1行导致未定义的行为。第4行甚至不会编译。由于这似乎很容易成为一个家庭作业问题,而且我不想完全放弃,快速阅读comp.lang.c FAQC language specification将解释原因。

答案 1 :(得分:8)

开玩笑,但也很严肃:

  • 第1行失败是因为您使用了strcpy( )函数,如果维护程序员在某些地方增加student数组的大小,可能会导致副本覆盖目标缓冲区的边界指出未来。这可能允许在某些环境中执行任意代码,并且是一个安全漏洞。

  • 第2行失败,因为您现在有两个同名内存块的名称,如果以后使用它们,可能会导致别名冲突和数据损坏。

  • 第3行失败是因为您拼错了Albert Einstein的名字。

  • 第4行失败,因为它无效C.

关键是,你需要有一个规范,然后才能就程序如何失败或有关失败进行有意义的讨论。

答案 2 :(得分:2)

strcpy(teacher, student);

此操作失败,因为您尚未使用malloc()向教师分配内存。它指向随机,并将随机写入。 UB即将开始

答案 3 :(得分:2)

除了别人说的话:
如果您使用的是C89编译器,第5行“失败”(*)

函数main的特殊之处在于它是程序启动时实现调用的函数。与C99不同,它的终止方式并不特别。返回类型不同于void 必须的函数(在C89中,除了main,在C99中)返回一些内容以避免未定义的行为。

C99中的

(*)在函数return 0;

的右括号之前有一个隐式main

答案 4 :(得分:0)

编译器会在/ *第4行* /抱怨。通过以这种方式声明学生,学生将表现为一个指向64字节块起始地址的常量指针。它不能被赋值,虽然它可以被引用(在第1 + 2行中)并且具有指向改变的存储器(在第3行中)。

答案 5 :(得分:-1)

第4行肯定会失败,因为声明char student[64]实际上将student定义为一个指向字符的常量指针。该assigment试图改变指针的值(而不是它指向的字符串),这将违反其常量性质。

第1行应该在运行时引起问题,但会通过编译器(可能会生成警告)。由于教学没有被赋予任何东西(即它是一个无效的指针),你不能将一个值复制到它指向的位置,因为它并不真正指向任何地方。