![](/img/trans.png)
[英]Why don't functions marked as “hidden” throw an error when called from external modules in gcc 4?
[英]Why don't this similar functions throw the same error?
我有两个具有相同返回类型的函数:
char * getRandomWord(char wordlist[WORDLIST_LENGTH][WORD_LENGTH]) {
int random = rand() % WORDLIST_LENGTH;
return wordlist[random];
}
char * revealInString(char * s, int * r) {
size_t strLength = strlen(s);
char revealedString[strLength + 1];
for (int i = 0; i < strLength; i++) {
revealedString[i] = '_';
}
for (int i = 0; i < strLength; i++) {
if (r[i] != NULL) {
int positionToReveal = r[i];
revealedString[positionToReveal] = s[positionToReveal];
}
}
revealedString[strLength - 1] = '\0';
return revealedString;
}
第一个工作正常,而我的IDE(CLion)在第二个工作中显示了一个问题: Value escapes the local scope
。
为什么第二个函数显示该错误,而第一个函数也返回没有问题的字符数组?
语法char revealedString[N]
定义了在堆栈上分配的VLA(C99功能)。
...但是您的revealInString
函数然后返回一个指向堆栈分配的内存的指针。 这是一个错误:当您的函数返回时,将弹出堆栈,因此revealedString
现在指向无效的内存。
相比之下,您的第一个示例将返回指向在调用函数之前分配的内存的指针。
尽管在堆栈上分配然后返回的函数可以工作(前提是调用者不做进一步的调用),但这是一个非常糟糕的主意,因为它取决于未定义的行为。
您可以通过以下两种方法解决此问题:
revealInString
之前,让调用方在堆栈上分配VLA calloc
或malloc
),并确保调用者完成调用后可以free
它们。 范例1:
char revealedStringBuffer[ strlen(s) + 1 ];
revealInString( revealedStringBuffer, r ); // and change `revealInString` to return void
范例2:
char * revealInString(char * s, int * r) {
size_t strLength = strlen(s);
char* revealedString = calloc( strLength + 1, sizeof(char) );
if( revealedString == NULL ) die("calloc failure.");
for (int i = 0; i < strLength; i++) {
revealedString[i] = '_';
}
for (int i = 0; i < strLength; i++) {
if (r[i] != NULL) {
int positionToReveal = r[i];
revealedString[positionToReveal] = s[positionToReveal];
}
}
revealedString[strLength - 1] = '\0';
return revealedString;
}
// Usage:
char* revealedString = revealInString( s, r );
free( revealedString );
它们都不返回数组。 他们返回一个指针(指向char
)。
在第二个函数中,返回的指针指向局部变量。 函数返回时,局部变量将被销毁,因此返回的指针无效。 这就是为什么编译器会警告您的原因。
在第一种情况下,您将返回调用方传递的指针,因此如果该指针有效,则在函数返回时它将仍然有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.