【问题标题】:Return a "char *tab[]" in a function C在函数 C 中返回“char *tab[]”
【发布时间】:2018-09-28 20:27:57
【问题描述】:

我试图创建一个函数来返回 char *tab[] 以填充 char *tab1[]

#include <stdio.h>
#include <string.h>
char * fill(){
        char *tab[2];
        tab[0] = "text 1";
        tab[1] = "text 2";
        return tab;
}

int main(){
        char *tab1[2];
        tab1 = fill();
        return 0;
}

我尝试使用strcpy,strncpy,返回一个char **,malloc。我每次只能复制一个索引,比如tab1[0] = tab[0],但是我需要一次性返回完整的数组。

我正在使用递归函数来填充 *tab[],为此我需要连接一些字符串和 var:

void fill(int n, char *x, char *y, char *z, char *tab[]){
        int i;
        char text[40];
        if(n == 1){
                strcpy(text, "text 1 ");
                strcat(text, x);
                strcat(text, " text 2 ");
                strcat(text, y);

                tab[0] = text;
        } else if(tab[n-1] == ""){
                strcpy(text, "text 1 ");
                strcat(text, x);
                strcat(text, " text 2 ");
                strcat(text, z);
                strcat(text, "\ntext 1 ");
                strcat(text, z);
                strcat(text, " text 2 ");
                strcat(text, y);

                tab[n-1] = text;
                if(n-1 > 1){
                        fill(n-1, x, z, y, tab);
                }
        }
}

最后我需要返回 tab[] 以填充主目录中的另一个选项卡:

int main(){
            int n = 2;
            char *tab1[n];
            fill(n, "a", "b", "c", tab1);
            return 0;
    }

【问题讨论】:

  • tab[0] = text; 将本地 text 分配给 tab[0]。这仅在函数结束之前有效,之后char text[40]; 不再有效。调用代码不能使用tab[0] 而不引起未定义的行为 (UB)。调用代码需要为连接的字符串提供内存,或者函数可以分配数据。你想要什么?
  • 您真的需要像第一个示例中那样返回一个数组,还是像第二个示例中那样填充调用者提供的数组?它们有点不同。
  • 我看到您尝试编写递归解决方案。这不是最好的方法。是否需要递归?如果是这样,为什么会有这个要求?

标签: c arrays string function


【解决方案1】:

首先,您的表是函数的本地表,并且它不存在于函数范围之外。

其次表不是指针不能像你那样把表作为指针在主函数中赋值。

char ** fill()
{
        char **tab = malloc(2 * sizeof (*tab));
        tab[0] = "text 1";
        tab[1] = "text 2";
        return tab;
}

int main()
{
        char **tab1;
        tab1 = fill();
        return 0;
}

【讨论】:

    【解决方案2】:

    您的现有代码存在一些问题。首先,这里:

            int n = 2;
            char *tab1[n]; /* here, the contents of tab1 are unspecified  */
            fill(n, "a", "b", "c", tab1); /* so here, you can't read them */
    

    也就是说,当fill 这样做时

       } else if(tab[n-1] == ""){
    

    假设tab[1](在第一次通话时)是您可以合法阅读的内容。不是,因为你从来没有在里面放任何东西。

    你绝对不能假设它恰好指向字符串文字"",你也不能假设它指向任何可取消引用的位置(所以你不能写!*tab[n-1]!strcmp(tab[n-1], "")或其他)。

    幸运的是,从您编写代码的方式来看,您永远需要检查此值,因为您对每个条目只写一次。因此,您可以删除该条件。

    接下来,您还有另一个问题,因为您分配的值是指向具有自动生命周期的本地 char 数组的指针:text。当函数返回时,它们都超出了范围,然后取消引用 tab1 中的 any 项是非法的。将分配更改为例如。

    tab[n-1] = strdup(text);
    

    会解决这个问题,但请注意调用者随后负责freeing 每个元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2012-02-18
      • 2018-09-03
      • 1970-01-01
      • 2023-02-16
      • 1970-01-01
      • 2010-09-27
      相关资源
      最近更新 更多