最近参加了很多公司的笔试和面试,经常会遇到这样一个问题。如下:
char* MyCopy(char *str) { char test[1024]; strcpy(test, str); return test; }
问题是请你找出这个函数的问题!
存在的疑问点:(我能想到的!大家还有什么疑点可以留言一起讨论)
(1)test这个函数是一个局部变量,在栈上分配的空间再把这个地址返回还能使用吗?(要点)
(2)还有就是这个str的长度如果超出了1024怎么办?
(3)str为空怎么办?
下面我就对这三个疑点谈谈我的看法
疑点1:
首先我们来做个测试
int main(int argc, char *argv[]) { char *pSource = "Test String"; char *pDest = MyCopy(pSource); cout<<pDest<<endl; return 0; }
结果:
难道这个还能访问吗?
那好既然能访问那我们在把这个测试程序改哈!看哈能不能访问。
char *pSource = "Test String";
char *pDest = MyCopy(pSource);
*(pDest + 1) = 'K';
cout<<pDest<<endl;
结果呢?
耶!难道真的可以使用吗?
但是我觉得不对啊。我又做了一个测试,定义了另一个函数如下:
void Fill() { char test[1024] = "FFFFFFFFFFFFFFFFFFFFFFF"; }
结果尽然是这样的。到这里大家应该明白了吧!
下面给出了它的大致内存模型
结论:由于test是个局部变量在函数返回时就已经告诉编译器0X10000000这个位置的空间是可以再分配给其他的局部变量的但由于我们返回了栈的地址所以我们就可以对他进行修改或者获取这个地址的数据,但一旦我们定义了其他的局部变量我们刚才的地址空间的数据是可以再分配出去的所以就有可能会覆盖我们先前的数据,这就是为什么刚开始时我们能获取和修改的原因。但是这样的使用是不安全的因为编译器没办法保证你的这个区域的数据不被覆盖。我读到的数据就是”脏数据“。
由于后两个疑问很好理解在这你我就不再说明了。
有什么说的不对的地方还望大家多多指点。