2012-03-12 58 views
0

问题是非常明显的,所以我只会告诉你一些代码:)有什么办法可以避免静态内存区溢出?

#include <stdio.h> 
#include <string.h> 
char *test1() 
{ 
    static char c; 
    char *p; 
    p = &c; 
    printf("p[%08x] : %s\n", (unsigned int)p, p); 
    return p; 
} 

void *test2() 
{ 
    static char i; 
    char *buf; 
    int counter = 0; 
    for(buf = (char *)&i ; ;counter += 8) 
    { 
     memset(buf + counter, 0xff, 8); 
     printf("write %d bytes to static area!\n", counter); 
    } 
} 

int main() 
{ 
    char *p; 
    p = test1(); 
    strcpy(p, "lol i asd"); 
    p = test1(); 
    strcpy(p, "sunus again!"); 
    p = test1(); 
    strcpy(p, "sunus again! i am hacking this!!asdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); 
    p = test1(); 
    test2(); 
    return 0; 
} 

首先我写了test1()。 正如你所看到的,那些strcpys应该会导致段错误,因为它显然访问非法的内存区域。我知道一些关于静态变量的基本知识,但这对我来说很奇怪。

然后我写了test2()。 最后,它引起了段错误,之后它写了将近4k字节。

所以,我不知道如何避免这种错误(静态变量溢出)发生?

为什么我可以访问这些静态内存区域? 我知道他们不在堆栈中,也没有堆积。

PS。也许我没有清楚地描述我的问题。我有几年的C编程经验;我知道如果这不是静态的,会发生什么。 现在静态变化几乎所有,我想知道为什么。

+1

如果您使用Shift键,您的问题会更容易阅读。 – 2012-03-12 04:44:36

+0

@Eric J .:或者至少学会正确使用它。 – BoltClock 2012-03-12 04:45:25

回答

1

未定义的行为就是这样 - undefined。它看起来可能正在工作,它可能会崩溃,它可能会偷走你的午餐钱。只是不要这样做。

+0

我知道,这是不正常的。不是静态的变量会导致错误错误发生之后,但这,只是隐藏.. – sunus 2012-03-12 04:49:00

+0

没有保证什么,看起来像一个错误会不管你碰巧使用您的变量的存储类别的发生。 – 2012-03-12 04:50:25

0

不能避免覆盖内存,你没有在C.

分配至于失败的方式...潜在何时,何地以及如何您的应用程序崩溃或其它怪异现象,完全取决于你的编译器,编译器标志和随机状态存储器在你的程序开始执行之前。您正在访问您不应该访问的内存,并且它在访问对操作环境的影响方面完全未定义。

管理内存(例如Java,C#)的语言会为您做这件事,但边界检查当然会有成本。

你当然可以使用内存管理库(替换为malloc/free/new/delete),它将尝试检测不正确的内存管理。当你超出内存页,这是4KB,所以运气好的话在它发生之前,你可以写完整的4K发生

1

分段故障,而如果下一个页面已经被利用 - 甚至不能保证。海湾合作委员会的堆栈保护有时可以帮助,但在这种情况下不能。 Valgrind也可以提供帮助。这些都不能保证。你最好自己照顾它。

0

通过了解您的存储区域有多大以及不在这些区域的边界之外进行书写,避免了这个问题。没有其他可靠的方法来处理这个问题。

+0

我的意思是,在test1中,我可以将静态字符c更改为静态字符c [2];然后让p = c。而且一切都保持不变。 – sunus 2012-03-12 07:57:33

相关问题