如何在 C 中递归 return 字符串值?
How to recursively return string value in C?
尝试在这里学到一些东西,而不是解决具体问题。请帮助我找到一些适用于这种情况的最佳实践,并在可能的情况下澄清原因。预先感谢您的帮助。
基本上,我是在已知限制内暴力破解一个非常简单的哈希算法。函数根据散列测试字符串(在长度限制内)的可能性,直到它与传递的散列匹配。然后递归应该停止所有迭代和 return 匹配的字符串。迭代有效,但是当找到答案时,函数的 each 运行 似乎没有通过调用同一函数 [=27] 获得值 returned =].
这是函数的代码,为清楚起见,添加了额外的注释:
//'hash' is the hash to be replicated
//'leading' is for recursive iteration (1st call should have leading=="")
//'limit' is the maximum string length to be tested
string crack(string hash, string leading, int limit)
{
string cracked=NULL, force=NULL, test=NULL;
//as per definition of C's crypt function - validated
char salt[3] = {hash[0], hash[1], '[=11=]'};
// iterate letters of the alphabet - validated
for(char c='A'; c<='z'; c++)
{
// append c at the end of string 'leading' - validated
test = append(leading,c);
// apply hash function to tested string - validated
force = crypt(test,salt);
// if hash replicated, store answer in 'cracked' - validated
if(strcmp(hash,force)==0)
{
cracked = test;
}
else
{
// if within length limit, iterate next character - validated
if(strlen(test)<=limit+1)
{
// THIS IS WHERE THE PROBLEM OCCURS
// value received when solution found
// is always empty string ("", not NULL)
// tried replacing this with strcpy, same result
cracked = crack_des(hash,test,limit);
}
}
// if answer found, break out of loop - validated
if(cracked){break;}
// test only alphabetic characters - validated
if(c=='Z'){c='a' - 1;}
}
free(test);
// return NULL if not cracked to continue iteration on level below
// this has something to do with the problem
return cracked;
} // end of function
从我对指针的一点回忆来看,我猜它是传递引用而不是值的东西,但我没有足够的知识来解决它。我已阅读 this thread,但此建议似乎无法解决问题 - 我尝试使用 strcpy 并得到相同的结果。
免责声明:这是 2018 年哈佛大学在 EDX 的 CS50 中的练习。它不会影响我的评分(已经提交了本周的两个完美练习,这是必需的)但是如上所述我正在学习。
Edit:将标签编辑回 C(如评论中所述,字符串来自 string.h,附加由我编码并多次验证 -稍后我会介绍 TDD)。感谢大家的评论;问题已解决并吸取了教训!
我在代码中发现了一个错误,但我不确定它是否是您问题的根本原因。
代码命中时:
strcmp(hash,force)==0
然后将'test'指向的字符串赋值给'cracked':
cracked = test;
然后命中这一行:
if(cracked){break;}
然后循环被打破,下一行:
free(test);
此行将释放 test 指向的字符串,请记住它与 'cracked' 指向的字符串相同,因此您 返回了一个已被释放的字符串 .
字符串会发生什么取决于您的编译器和 libc。您可以尝试通过为 'cracked':
分配内存来解决此问题
cracked = strdup(test);
另外,还有'test'和'force'字符串导致的内存泄漏,不过应该与你的问题无关。
尝试在这里学到一些东西,而不是解决具体问题。请帮助我找到一些适用于这种情况的最佳实践,并在可能的情况下澄清原因。预先感谢您的帮助。
基本上,我是在已知限制内暴力破解一个非常简单的哈希算法。函数根据散列测试字符串(在长度限制内)的可能性,直到它与传递的散列匹配。然后递归应该停止所有迭代和 return 匹配的字符串。迭代有效,但是当找到答案时,函数的 each 运行 似乎没有通过调用同一函数 [=27] 获得值 returned =].
这是函数的代码,为清楚起见,添加了额外的注释:
//'hash' is the hash to be replicated
//'leading' is for recursive iteration (1st call should have leading=="")
//'limit' is the maximum string length to be tested
string crack(string hash, string leading, int limit)
{
string cracked=NULL, force=NULL, test=NULL;
//as per definition of C's crypt function - validated
char salt[3] = {hash[0], hash[1], '[=11=]'};
// iterate letters of the alphabet - validated
for(char c='A'; c<='z'; c++)
{
// append c at the end of string 'leading' - validated
test = append(leading,c);
// apply hash function to tested string - validated
force = crypt(test,salt);
// if hash replicated, store answer in 'cracked' - validated
if(strcmp(hash,force)==0)
{
cracked = test;
}
else
{
// if within length limit, iterate next character - validated
if(strlen(test)<=limit+1)
{
// THIS IS WHERE THE PROBLEM OCCURS
// value received when solution found
// is always empty string ("", not NULL)
// tried replacing this with strcpy, same result
cracked = crack_des(hash,test,limit);
}
}
// if answer found, break out of loop - validated
if(cracked){break;}
// test only alphabetic characters - validated
if(c=='Z'){c='a' - 1;}
}
free(test);
// return NULL if not cracked to continue iteration on level below
// this has something to do with the problem
return cracked;
} // end of function
从我对指针的一点回忆来看,我猜它是传递引用而不是值的东西,但我没有足够的知识来解决它。我已阅读 this thread,但此建议似乎无法解决问题 - 我尝试使用 strcpy 并得到相同的结果。
免责声明:这是 2018 年哈佛大学在 EDX 的 CS50 中的练习。它不会影响我的评分(已经提交了本周的两个完美练习,这是必需的)但是如上所述我正在学习。
Edit:将标签编辑回 C(如评论中所述,字符串来自 string.h,附加由我编码并多次验证 -稍后我会介绍 TDD)。感谢大家的评论;问题已解决并吸取了教训!
我在代码中发现了一个错误,但我不确定它是否是您问题的根本原因。
代码命中时:
strcmp(hash,force)==0
然后将'test'指向的字符串赋值给'cracked':
cracked = test;
然后命中这一行:
if(cracked){break;}
然后循环被打破,下一行:
free(test);
此行将释放 test 指向的字符串,请记住它与 'cracked' 指向的字符串相同,因此您 返回了一个已被释放的字符串 .
字符串会发生什么取决于您的编译器和 libc。您可以尝试通过为 'cracked':
分配内存来解决此问题cracked = strdup(test);
另外,还有'test'和'force'字符串导致的内存泄漏,不过应该与你的问题无关。