c带指针的strcat

c带指针的strcat,c,pointers,memory-management,C,Pointers,Memory Management,我想用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 *

我想用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;
}

可能我没有正确使用strcat的功能。。。但我真的不知道该修复什么…

您正在将
s1[I]
,这是一个
char
,转换为一个无意义的
const char*
指针:

strcat((char*)commonSequence, (const char *)s1[i]);
您还将
commonSequence
char**
转换为
char*
,这将不起作用。您可能需要以下内容:

strcat(*commonSequence, ((const char *)s1)[i]);
但是,为
commonSequence
分配内存的方式确实有问题。看起来您正在构建一个字符串列表,而没有分配字符串本身

 strcat((char*)commonSequence, (const char *)s1[i]);

strcat需要一个指针,您在那里使用
(const char*)s1[i]
所做的是访问字符,然后将其作为指针输入。也就是说,不是strcat应该开始的地址,而是给它字符的值。

您正在为字符串的指针分配内存,而不是为字符串本身分配内存。
strcat()
的第一个参数似乎应该是
*commonSequence

您使用
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个字节,而不是结构的大小。

您需要传递s1[i]的地址。简单地强制转换它不会使其成为有效地址。同样地将字符**强制转换为字符*将不会产生您期望的结果。您应该取消对它的引用以访问存储在char中的char*指针**

strcat( *commonSequence, &s1[i] );

也就是说,代码的其余部分看起来可疑。我想知道你到底想干什么?但你明确要求我们不要质疑这一点

((const char*)s1)[i]
仍然具有char而不是char*类型。它不需要强制转换为const,这意味着
strcat()
不会修改数据。只有
&s1[i]
才能使第二个参数在语法上正确,尽管我没有说任何关于语义的内容-我同意你的观点,原始代码是v。臭味。代码中大量不必要和/或不适当的强制转换应该会敲响警钟。只有当你100%确定你知道你在做什么,才应该被应用,因为它会沉默其他有用的编译器错误/警告。@保罗:这是当初学者尝试用C++编译器编译C时发生的事情……(嗨,Clifford,该函数的目的是寻找最长的公共子字符串(但它只是原型)@Radek:我很确定,在没有strcat或动态内存的情况下,这是可以实现的。如果要查找字符串,它会返回char**例如!如果不强制转换commonSequence,它将在编译时导致错误:main.cpp:9:错误:从“void*”到“char**”的转换无效malloc在写入时返回void*.btw这里的例子十:它应该被铸造…实际上“不从Maloc中返回返回值……不是普通序列……”然后你写C++,而不是C。它们是不同的语言,使用<代码> MalOC 代替C++ > > < <代码> >是一个坏主意,除非你试图与需要释放的C代码进行接口。
strcat( *commonSequence, &s1[i] );