来自 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 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]。对不起,过去了,我也对代码进行了更正。

以上是关于来自 C 函数的多维字符数组返回错误的主要内容,如果未能解决你的问题,请参考以下文章

《C语言程序设计》指针

如何从函数返回多维 Mat 数组

python ctypes中的多维char数组(字符串数组)

从 C 中的函数返回多维数组

在c中使用多维数组存储来自用户的一行,并根据字长按降序返回该行中的单词

C/C++编程笔记:数组和字符串丨多维数组详解