我想用C编写这个示例函数(请不要判断那段代码的目的,它只用于学习C)。它应该使用动态分配内存来消耗更多的内存,而不是必需的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char ** LCS ( char * s1, char * s2 ) {
int i, ii, myI;
char ** commonSequence = (char**) malloc(1 * sizeof (char**));
*commonSequence = NULL;
int commonChars = 0;
for (i = 0; i < (int)strlen(s1);i++) {
for (ii = 0; ii < (int)strlen(s2); ii++) {
if (s1[i] == s2[ii]) {
commonChars++;
if (commonChars > 1) {
commonSequence = (char**) realloc(commonSequence, (commonChars+1) * sizeof (char**));
strcat((char*)commonSequence, (const char *)s1[i]);
}
i++;
}
}
}
return commonSequence;
}
int main ( int argc, char * argv [] ) {
char ** output = LCS((char*)"AATK", (char*)"AABC");
printf("\n\nCommon: %s", *output);
free(output);
return 0;
}
上面的代码导致“分段错误”错误(可能是内存分配错误或类似的错误)。当我在Valgrind中运行时,它会输出:
==29381== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 3)
==29381==
==29381== 1 errors in context 1 of 1:
==29381== Invalid read of size 1
==29381== at 0x4028A80: strcat (in /usr/lib/valgrind/vgpreload_memcheck-x86-l inux.so)
==29381== by 0x80485BA: LCS(char*, char*) (main.cpp:19)
==29381== by 0x8048626: main (main.cpp:31)
==29381== Address 0x41 is not stack'd, malloc'd or (recently) free'd
可能我没有正确使用 strcat 功能......但实际上我不知道该修复什么......
答案 0 :(得分:2)
您正在将s1[i]
char
投射到无意义的const char *
指针中:
strcat((char*)commonSequence, (const char *)s1[i]);
您还要将commonSequence
从char **
转换为char *
,这将无效。你可能想要这样的东西:
strcat(*commonSequence, ((const char *)s1)[i]);
但是你为commonSequence
分配内存的方式确实有问题。看起来你正在构建一个字符串列表,而不是自己分配字符串。
答案 1 :(得分:2)
您对malloc
的使用是假的,但由于数字恰好正确,错误可能不会被捕获。这一行:
char ** commonSequence = (char**) malloc(1 * sizeof (char**));
应为:
char ** commonSequence = malloc(1 * sizeof (char*));
或者最好:
char ** commonSequence = malloc(1 * sizeof *commonSequence);
最终形式是最好的,因为如果您更改commonSequence
的类型,它不需要任何更改。至于原始行的实际问题,您需要根据要指向的对象的大小进行分配,而不是指向它的指针的大小。在实践中,由于两者都是指针,它们在现代真实世界的机器上将具有相同的大小,但它仍然是一个严重的概念错误,当您将不正确的模式应用于非指针类型时,它可能会咬你。例如,这会导致内存损坏/未定义的行为:
struct foobar *foo = malloc(1 * sizeof (struct foobar *));
因为它只分配4或8个字节而不是结构的大小。
答案 2 :(得分:0)
strcat((char*)commonSequence, (const char *)s1[i]);
strcat需要一个指针,你在(const char *)s1[i]
做的是你正在访问该角色,然后将其作为指针给出。也就是说,不是strcat应该开始的地址,而是给它字符的值。
答案 3 :(得分:0)
您为指向字符串的指针分配内存,但不为字符串本身分配内存。 strcat()
的第一个参数似乎应该是*commonSequence
。
答案 4 :(得分:0)
你需要传递s1 [i]的地址。简单地投射它不会使它成为有效的地址。同样将char **转换为char *将不会产生您期望的结果。您应取消引用它以访问存储在char **
中的char *指针strcat( *commonSequence, &s1[i] );
也就是说,其余的代码看起来很可疑。我想知道你到底想要的是什么?但你明确要求我们不要质疑!