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

时间:2010-09-22 18:36:11

标签: 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);

3 个答案:

答案 0 :(得分:1)

Permute中的

char str[5];在堆栈中并在您退出Permute后丢失。退出Permute后,output[k]将指向未定义的位置。

答案 1 :(得分:1)

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

此外,在Permute中,您使用指向str的指针(函数外部不存在)覆盖指针值。你应该把str的内容strcpy到输出[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 );

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

答案 2 :(得分:1)

output = malloc(sizeof(char*) * (words * 2));

好的,您创建了output[0]output[1],......但他们的价值是什么?

output[0]char * ...它指向哪里?

并且您无法将Permute(str)中的本地变量的地址复制到output。一旦函数返回,该对象就不再存在。