堆栈内存上的free()

我在Solaris上支持一些c代码,至少我认为它是奇怪的:

char new_login[64]; ... strcpy(new_login, (char *)login); ... free(new_login); 

我的理解是,由于变量是本地数组,因此内存来自堆栈而不需要释放,而且由于没有使用malloc / calloc / realloc,因此行为未定义。

这是一个实时系统,所以我认为这是一个浪费周期。 我错过了一些明显的东西吗

你只能释放()你从malloc(),calloc()或realloc()函数得到的东西。 释放堆栈中的某些内容会产生未定义的行为,您很幸运,这不会导致程序崩溃或更糟。

考虑一个严重的错误,并尽快删除该行。

不,这是一个错误。

根据免费(3)….

free()释放ptr指向的内存空间,该内存空间必须由之前调用malloc(),calloc()或realloc()返回。 否则,或者如果之前已经调用了free(ptr),则会发生未定义的行为。 如果ptr为NULL,则不执行任何操作。

因此,您的程序中发生了未定义的行为。

肯定是一个bug。 free()必须只用于堆alloc’d内存,除非它被重新定义为完全不同的东西,我怀疑是这种情况。

free()肯定是个bug。
但是,这里可能存在另一个错误:

 strcpy(new_login, (char *)login); 

如果函数没有迂腐地确认登录是63个或更少的字符以及相应的空终止,则此代码具有经典的缓冲区溢出错误。 如果恶意方可以用正确的字节填充登录,它们可以覆盖堆栈上的返回指针并执行任意代码。 一个解决方案是:

 new_login[sizeof(new_login)-1]='\0'; strncpy(new_login, (char *)login, sizeof(new_login)-1 ); 

在大多数情况下,你只能释放()在堆上分配的东西。 见http://www.opengroup.org/onlinepubs/009695399/functions/free.html 。

但是: 做你想要做的事情的一种方法是限制堆栈上分配的临时变量。 像这样:

 { char new_login[64]; ... /* No later-used variables should be allocated on the stack here */ strcpy(new_login, (char *)login); } ... 

谢谢。 很高兴看到我不疯狂。 此外,strcpy没有边界检查。 我通常使用strncpy来避免这样的事情。