c - 创建指向 char 指针的笛卡尔积的困难

标签 c pointers

作为输入,我有一个指向 char 指针的指针,其中包含:

{"ab", "cd"}

作为输出,我需要创建以下笛卡尔积:

{"abab", "abcd", "cdab", "cdcd"}

我创建了一个函数,它接收“ab, cd”和一个指向用于保存结果集的 char 指针的指针。尽管函数内部似乎一切正常,但一旦退出,我的输出仍然是空的。我想我在串联过程中做错了什么,但我不确定是什么。

我的代码是这样的:

#include <stdio.h>

void Permute(char**, int, char**);

main() {
    // my input
    int words = 2;
    char **input;
    input = malloc(sizeof(char*) * words);
    input[0] = "ab";
    input[1] = "cd";

    // compute how much memory we need
    char **output;
    output = malloc(sizeof(char*) * (words * 2));

    // start permutation
    Permute(input, words, output);

    // show output
    int i = 0;
    for(i = 0; i < (words * 2); ++i) {
        // should print: {abcd, abab, cdab, cdcd} 
        // but nothing gets printed
        printf("%s\n", output[i]); 
    }
    free(input);
    free(output);
}

void Permute(char **input, int words, char **output){
    int i = 0, j = 0, k = 0;
    char str[5];
    for(i = 0; i < words; ++i) {
        for(j = 0; j < words; ++j) {
            strcpy (str, input[i]);
            strcat (str, input[j]);
            output[k] = str;
            // at this point concatenation is printed correctly
            printf("%s\n", output[k]); correctly
            ++k;
        }
    }
}

编辑

感谢 Goz 的评论,我更新了我的函数。现在,一个指向 char 的指针被分配,指向连接,然后存储在 output[k] 中。这样在激活函数时不会丢失数据:

void Permute(char **input, int words, char **output){
    int i = 0, j = 0, k = 0;
    char *p;
    for(i = 0; i < words; ++i) {
        for(j = 0; j < words; ++j) {
            p = malloc(sizeof(char*) * 5);
            strcpy(p, input[i]);
            strcat (p, input[j]);
            output[k] = p;
            printf("%d %s \n", k, output[k]); 
            ++k;
        }
    }
}

编辑

在将结果传递给 Permute 函数之前分配保存结果的缓冲区:

    // compute how much memory we need
    // allocate space for 4 pointers to char
    char **output = malloc(sizeof(char*) * 4); 
    int i = 0;
    // pre-allocate space for every pointer 
    for(i = 0; i < 4; i++)
       output[i] = malloc( sizeof( char ) * 5 ); 

编辑

在清除指向 char 指针的指针之前释放 char 指针指向的所有内存:

    // free memory
    for(i = 0; i < 4; i++ )
       free( output[i] );
    free(output);

    for(i = 0; i < 2; i++ )
       free(input[i]);
    free(input);

最佳答案

有几个问题。首先你分配一个char*。然后您将它分配给一个 char** 并期望它具有二维。它没有。您需要 malloc 一组 char* 指针(4 * 无论您的指针大小是多少...即 sizeof(char* )),然后为每个指针 malloc 5 个字节。

此外,在 Permute 中,您用指向 str 的指针(函数外不存在)覆盖指针值。您应该将 str 的内容 strcpy 到 output[k]。

对评论的回答:是的,这会起作用,但建议在进入循环之前分配缓冲区。

char** ptr = malloc( sizeof( char* ) * 4 );
for( int i = 0; i++; i < 4 )
{
   ptr[i] = malloc( sizeof( char ) * 4 ); // sizeof( char ) == 1 but its a good habit to get into.
}

然后如前所述将临时数组strcpy到相关的char*数组中。

此外请记住,当您释放内存时,您需要执行与上述循环相反的操作。即解除分配 4 个单独的数组,然后解除分配指针数组。即:

for( int i = 0; i++; i < 4 )
{
   free( ptr[i] );
}
free( ptr );

即调用 malloc 的所有 5 次都会遇到相应的释放。如果先释放 ptr 数组,则无法保证内存有效。因此存储在该数组中的 4 个指针可能不再有效。所以先释放它们,然后再释放指针数组。

关于c - 创建指向 char 指针的笛卡尔积的困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3772534/

相关文章:

c - Trie实现逻辑错误?

c - 在进程树中查找子进程的级别

c - 为什么允许我们更改 "const"限定变量的值?为什么允许指针而不是赋值?

将分数转换为 float

c - 错误 : initializer element is not constant

c - 错误调用的对象不是函数或函数指针

c - 在没有段错误的结构中使用指针

c++ - 使用 WriteProcessMemory 和指针写入另一个进程的内存

c++ - 为什么我在第一个代码中出现段错误,但在第二个代码中却没有?

c - 为什么将字符串直接传递给 printf 可以正常工作?