堆栈内存上的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来避免这样的事情。