来自 C 函数的多维字符数组返回错误
Posted
技术标签:
【中文标题】来自 C 函数的多维字符数组返回错误【英文标题】:Multidimensional Char Array return error from a C function 【发布时间】:2015-10-31 13:27:30 【问题描述】:我在 C 中有这样一个函数:
char **collect_character_distribution(char *buffer, long lSize)
printf("Collecting character distribution...\n");
long x;
char distribution[256][2] = 0;
for (x = 0; x < lSize; x++)
distribution[(int)buffer[x]][0] = (char) buffer[x];
distribution[(int)buffer[x]][1]++;
return (char **) distribution;
我需要从上面的函数中返回二维分布数组。我的主要功能如下:
int main()
char *buffer;
long lSize;
struct Bar result = funct();
char **distribution;
buffer = result.x;
lSize = result.y;
distribution = collect_character_distribution(buffer, lSize);
printf("%s\n", distribution);
//struct Bar encoding_tree = generate_encoding_tree(distribution);
return 0;
我收到以下错误:
警告:函数返回局部变量的地址 [-Wreturn-local-addr]
我该如何解决这个问题?
【问题讨论】:
***.com/questions/6897914/…的可能重复 您在循环中创建了一个变量,并且您试图将其地址传递给外部,这是没有意义的,因为该变量一旦失去作用域就会被销毁 @Arc676:有趣的案例 - 虽然重复涉及 完全相同的消息(并且 OP 没有看到它或没有寻找它),但我发现自己质疑是否一般来说,公认的答案是可取的。它甚至不回答问题! 【参考方案1】:您收到此错误是因为该数组是一个局部变量,并且您将其传递到其范围之外。
你需要为此使用动态分配
char **array = malloc(20 * sizeof(char *));
int i;
for(i=0; i != 20; ++i)
array[i] = malloc(20 * sizeof(char));
现在您可以轻松返回array
编辑 1
你要做的就是改变
char distribution[256][2];
这个到
char **array = malloc(20 * sizeof(char *));
int i;
for(i=0; i != 20; ++i)
array[i] = malloc(20 * sizeof(char));
编辑 2
要打印字符串,你应该循环
for(i=0; i<20; i++)
printf("%s\n", distribution[i]);
【讨论】:
哈里斯,你能完整地给出你的答案吗? @yusuf 看看你现在能不能理解 Haris,现在我在主函数上收到此错误:格式“%s”需要“char *”类型的参数,但参数 2 的类型为“char **”[-Wformat=]跨度> @yusuf offcourse,你现在有一个2D array
或 char
。您需要一个循环来打印其中的所有strings
。
@yusuf,试试我所做的改变【参考方案2】:
您正在返回一个指向在函数中本地声明的变量的指针。您应该做的是在需要这些结果的范围内声明要存储结果的变量。然后将指向该变量的指针传递给要写入的函数。大致如下:
void collect_character_distribution(char *buffer, long lSize, char distribution[256][2])
printf("Collecting character distribution...\n");
long x;
for (x = 0; x < 256; x++)
distribution[(int)x][0] = (char) x;
for (x = 0; x < lSize; x++)
distribution[(int)buffer[x]][1]++;
int main()
char *buffer;
long lSize;
struct Bar result = funct();
char distribution[256][2] = 0;
buffer = result.x;
lSize = result.y;
collect_character_distribution(buffer, lSize, distribution);
int i;
for ( i = 0; i < 256; i++ )
printf("%c: %d\n", distribution[i][0], distribution[i][1]);
//struct Bar encoding_tree = generate_encoding_tree(distribution);
return 0;
【讨论】:
嘿 yusuf,您的代码中还有其他几个错误会引发错误,这些错误与您的原始问题是分开的。比如你需要实际分配distribution
,不能像printf
那样打印二维char数组;您将需要遍历数组中的字符串。我编辑了我的代码以反映我的意思,但我没有尝试编译或调试。
如果没有看到您的完整代码并试图缩小抛出段错误的范围,很难说这是从哪里来的。如果您无法调试它,我建议您在此处接受其中一个答案并提出一个新问题。
@MarcoTompitak @yusuf 在main
中声明distribution
为char ** distribution
。在您的代码中,您可以越界访问索引,因此是 UB。
发现一个问题,我编辑了我的代码,就像这样对我有用。
您打印的可能不是您想要的。从您的代码中猜测,您可能想要a: 1, b:4
之类的东西?我更新了代码。【参考方案3】:
您可以将char **distribution
作为参数传递并在您的函数中使用:
分布=新字符* [256]; 分布[0] = 新字符[2]; 分布[1] = 新字符[2];
那么你不需要从你的函数中返回distribution
数组。问题是局部变量在其作用域结束后被销毁,在您的情况下 distribution
仅存在于函数 collect_character_distribution
中。
【讨论】:
Ardavel,你能完整地给出你的答案吗?【参考方案4】:它的简单消息是你的函数return
是一个局部变量。您的数组在功能块之外不存在。
在你的函数中你可以这样做 -
char **distribution;
distribution=malloc(256*sizeof(char *));
for(int i=0;i<256;i++)
distribution[i]=malloc(20*sizeof(distribution[0][0]));
同样在main
,这个-
printf("%s\n", distribution);
distribution
属于 char **
类型,您不能将其传递给 %s
说明符。
你可以循环执行 -
for(int i=0;i<256;i++)
printf("%s\n", distribution[i]);
编辑-
#include <stdio.h>
#include <stdlib.h>
char **collect_character_distribution(char *buffer, long lSize);
int main()
char *buffer;
long lSize;
struct Bar result = funct();
char **distribution;
buffer = result.x;
lSize = result.y;
distribution = collect_character_distribution(buffer, lSize);
for(int i=0;i<256;i++)
printf("%s\n", distribution[i]);
//struct Bar encoding_tree = generate_encoding_tree(distribution);
for(int i=0;i<256;i++)
free(distribution[i]);
free(distribution);
return 0;
char **collect_character_distribution(char *buffer, long lSize)
printf("Collecting character distribution...\n");
long x;
char **distribution;
distribution=malloc(256*sizeof(char *));
for(int i=0;i<256;i++)
distribution[i]=malloc(20*sizeof(distribution[0][0]));
for (x = 0; x < lSize; x++)
distribution[(int)buffer[x]][0] = buffer[x];
distribution[(int)buffer[x]][1]++;
return distribution;
【讨论】:
我不明白反对票。请发表评论。 我对你投了赞成票 ameyCU :) 你能简单解释一下你的答案吗? 你在函数中声明的@Yusuf数组是一个局部变量,它不能在函数外访问,当你这样做时,编译器会发出警告。为此,我们声明一个char **
并为其分配内存,因此即使在函数终止后它也会保留它的值。
ameyCU,你能完整地给出你的答案吗?
@Yusuf 哦,是的,要么在那里写*(distribution+i)
,要么写distribution[i]
。对不起,过去了,我也对代码进行了更正。以上是关于来自 C 函数的多维字符数组返回错误的主要内容,如果未能解决你的问题,请参考以下文章
python ctypes中的多维char数组(字符串数组)