繁体   English   中英

c strcat与指针

[英]c strcat with pointers

我想用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函数...但是我实际上不知道要解决什么...

您正在将s1[i] (它是一个char )转换为无意义的const char *指针:

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

您还正在将commonSequencechar **转换为char * ,这是行不通的。 您可能想要类似的东西:

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

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

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

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

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

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

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

就是说,其余的代码看起来很可疑。 我想知道您实际上想达到什么目的? 但是您明确要求我们不要质疑!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM