我决定在C中创建一个reverse(s)
函数,在这个过程中,我在编译过程中遇到了2条警告消息。
alexander@debian:~/Dropbox/GitRepo/M2MPL/text$ make reverse
cc reverse.c -o reverse
reverse.c: In function 'reverse':
reverse.c:29:2: warning: return makes integer from pointer without a cast [enabled by default]
reverse.c:29:2: warning: function returns address of local variable [enabled by default]
alexander@debian:~/Dropbox/GitRepo/M2MPL/text$
由于他们是警告,我试图忽略它们并运行程序,当我使用Dropbox
输入一个字符数组scanf("%s", str1);
时,结果显示为Segmentation Fault
。
alexander@debian:~/Dropbox/GitRepo/M2MPL/text$ ./reverse
Enter a string to reverse: Dropbox
Segmentation fault
alexander@debian:~/Dropbox/GitRepo/M2MPL/text$
这是我对reverse(s)
功能的实现:
/* reverse: returns a reversed string of s */
char reverse(char s[])
{
int i, len=strlen(s);
char result[LIMIT];
for (i = len; i >= 0; --i) {
result[len-i] = s[i];
}
return result;
}
我需要帮助才能知道为什么我得到Segmentation fault
而不是xobporD
,如果可能的话,建议解决这个问题。
答案 0 :(得分:2)
首先:
编译器不会只是为了好玩而警告你。如果忽略编译器警告,你的程序崩溃不应该感到惊讶。
将指针返回到自动变量,该变量在函数末尾超出范围。返回给调用者的指针无效,因为它指向reverse
函数返回后不再存在的对象。
另一个问题是您复制的第一个字符是'\0'
,因此结果字符串为空。您需要反转字符串的字符,但仍然将'\0'
放在字符串的末尾。
答案 1 :(得分:2)
第一个警告意味着reverse
函数的签名所指示的返回类型与您实际返回的变量的类型不匹配。预期的类型为char
,您将返回char *
(因为result
衰减到这样的指针)。因此编译器将指针转换为整数(char
),这通常不是程序员的意图。
第二个问题是您返回局部变量的地址,并且该函数返回后该变量不再可用,因为自动存储的工作方式。如果要返回指向某些数据的指针,则必须全局分配(在函数内声明static
或全局声明),或者必须动态分配。
答案 2 :(得分:0)
问题代码中存在一些缺陷。
以下代码修复了上述问题。它返回已分配的堆中的字符串'内存给来电者。 (当不再需要时,调用者应释放()内存。):
/* reverse: returns a reversed string of s */
char *reverse(char *s)
{
int i, len=strlen(s);
char *result = malloc(len+1);
if(result)
{
result[len] = '\0';
for(i = len; i >= 0; --i)
result[len-i] = s[i];
}
return(result);
}