【问题标题】:Multidimensional Char Array return error from a C function来自 C 函数的多维字符数组返回错误
【发布时间】: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]

我该如何解决这个问题?

【问题讨论】:

  • 您在循环中创建了一个变量,并且您试图将其地址传递给外部,这是没有意义的,因为该变量一旦失去作用域就会被销毁
  • @Arc676:有趣的案例 - 虽然重复涉及 完全相同的消息(并且 OP 没有看到它或没有寻找它),但我发现自己质疑是否一般来说,公认的答案是可取的。它甚至不回答问题!

标签: c arrays


【解决方案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 arraychar。您需要一个循环来打印其中的所有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 中声明distributionchar ** 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]。对不起,过去了,我也对代码进行了更正。
猜你喜欢
  • 2014-07-23
  • 2018-01-05
  • 2012-12-08
  • 2012-04-24
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
相关资源
最近更新 更多