作为输入,我有一个指向 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/