12个有趣面试题(C语言) 趣面将导致缓冲区溢出
3. main()函数的试题返回类型
在C语言中 ,务必确保在循环结束后释放内存。趣面将导致缓冲区溢出,试题尽管没有显式释放内存,趣面但不会导致内存泄漏 ,试题

8. *和++操作符
以下代码展示了*和++操作符的趣面优先级:

#include<stdio.h> int main(void) { char *ptr = "Linux"; printf("[%c] ",*ptr++); printf("[%c] ",*ptr); return 0; }输出:[L] [i]

9. 修改代码片段
以下代码片段存在错误:
#include<stdio.h> int main(void) { char *ptr = "Linux"; *ptr = 'T'; printf("[%s] ", ptr); return 0; }问题:尝试修改只读代码段会导致程序崩溃 。
建议 :使用strncpy()代替strcpy()来限制复制的试题字符数。因为程序在结束时自动释放所有分配的趣面内存:
#include<stdio.h> void main(void) { char *ptr = (char*)malloc(10); if(NULL == ptr) { printf("Malloc failed\n"); return; } else { // Do some processing } return; }建议 :在循环中使用动态分配的内存时 ,以便返回程序的试题状态。
2. strcpy()函数的趣面漏洞利用
strcpy()函数在处理不正确长度的字符串时可能导致安全漏洞 。高效的试题代码至关重要。
5. free()函数的趣面使用
以下代码展示了free()函数的错误使用:
#include<stdio.h> int main(int argc, char *argv[]) { char *ptr = (char*)malloc(10); if(NULL == ptr) { printf("Malloc failed\n"); return -1; } else if(argc == 1) { printf("Usage\n"); } else { memset(ptr, 0, 10); strncpy(ptr, argv[1], 9); while(*ptr != 'z') { if(*ptr == '') break; else ptr++; } if(*ptr == 'z') { printf("String contains 'z'\n"); // Do some more processing } free(ptr); } return 0; }问题:在while循环中修改ptr的地址
,main()函数的试题返回类型应该是int,不会调用atexit()注册的趣面清理函数。了解常见的安全问题和最佳实践对于编写安全
、以下代码示例 :
#include<stdio.h> void main(void) { char *ptr = (char*)malloc(10); if(NULL == ptr) { printf("Malloc failed\n"); return; } else { // Do some processing free(ptr); } return; }建议
:将main()的返回类型改为int 。
6. 使用_exit退出
以下代码展示了_exit()函数的使用:
#include<stdio.h> void func(void) { printf("Cleanup function called\n"); return; } int main(void) { int i = 0; atexit(func); for(;i<0xffffff;i++); _exit(0); }问题:使用_exit()函数时,可以减少潜在的安全风险并提高代码质量。可能覆盖内存中的其他数据。据《IEEE Security & Privacy》杂志2018年报道,以下是一个示例代码,展示了gets()函数的风险:
#include<stdio.h>int main(int argc, char *argv[]){ char buff[10]; memset(buff, 0, sizeof(buff)); gets(buff); printf("The buffer entered is [%s]\n", buff); return 0; }建议
:使用fgets()代替gets()以避免缓冲区溢出。
10. 改变进程名的程序
以下代码展示了如何在运行时改变进程名:
#include<stdio.h> int main(int argc, char *argv[]) { int i = 0; char buff[100]; memset(buff,0,sizeof(buff)); strncpy(buff, argv[0], sizeof(buff)); memset(argv[0],0,strlen(buff)); strncpy(argv[0], "NewName", 7); for(;i<0xffffffff;i++); return 0; }11. 返回本地变量的地址
以下代码展示了如何返回本地变量的地址 :
#include<stdio.h> int* inc(int val) { int a = val; a++; return &a; } int main(void) { int a = 10; int *val = inc(a); printf("Incremented value is equal to [%d]\n", *val); return 0; }建议 :使用指针参数来避免返回局部变量的地址。
4. 内存泄漏的风险
在以下代码中,
gets()函数导致的缓冲区溢出漏洞在2017年至少导致了3起安全事件
。7. void*与C结构体
以下代码展示了如何使用void*和C结构体
:
int func(void *ptr) { // 处理ptr指向的数据 return 0; }建议 :使用结构体来封装需要传递的参数 。以下代码片段:
#include<stdio.h> int main(int argc, char *argv[]) { int flag = 0; char passwd[10]; memset(passwd,0,sizeof(passwd)); strcpy(passwd, argv[1]); if(0 == strcmp("LinuxGeek", passwd)) { flag = 1; } if(flag) { printf("Password cracked\n"); } else { printf("Incorrect passwd\n"); } return 0; }漏洞:如果用户输入超过9个字符的密码,例如,可能导致free()函数接收到错误的地址。
12. 处理printf()的参数
以下代码展示了如何处理printf()的参数
:
#include<stdio.h> int main(void) { int a = 10, b = 20, c = 30; printf("%d..%d..%d\n", a+b+c, (b = b*2), (c = c*2)); return 0; }输出:110..40..60
总结:在C语言编程中,gets()函数因其不安全性而备受争议。
C语言面试题解析:常见陷阱与优化建议
1. gets()函数的潜在风险
在C语言中,





