【问题标题】:How to return a 2D array in a C function [duplicate]如何在C函数中返回二维数组[重复]
【发布时间】:2023-05-09 02:14:02
【问题描述】:

我目前正在做一个学校项目。我必须开发一个程序来控制 IP 并开发他的规范。

我被一个双向的char数组困住了。我不知道如何正确退货。

char** extraction_ip(char **ip){
   char *ch;
   char ipv4 [4][3];
   int i = 0;
   ch = *ip;
   *ipv4 [i]=strtok(ch, ".");
   while (ipv4 [i]!= NULL){
      i++;
      *ipv4 [i]=strtok(NULL, ".");
   }
   return ipv4;
}

在此之前,我尝试通过创建一个 void 函数来做到这一点: enter image description here

【问题讨论】:

  • 通常的做法是: 1. 在调用方法中声明一个变量,并将指向它的指针和大小信息作为参数传递给函数。 2.通过malloc动态分配。无论哪种方式,它都应该是结构而不是原始数组,以便更好地传达含义。
  • 或者更好,更一般的问题:*.com/questions/11656532/returning-an-array-using-c
  • 这段代码很混乱。主要问题是指向指针的指针不是二维数组,不能指向一个。它只能指向指针数组中的第一项,没有别的。
  • Correctly allocating multi-dimensional arrays 解释了二维数组和基于指针的查找表之间的区别。

标签: c multidimensional-array


【解决方案1】:

尽量避免……

数组不是 C 语言中的一等公民,更不用说多维数组,因此您只能返回指向其第一个元素的指针。它几乎可以像真正的数组一样使用,除了你不能在它上面使用sizeof,当你返回一个指向自动数组的指针时,数组在函数返回时结束它的生命周期,调用者留下一个悬空指针.从 C 中的函数返回数组有 3 种方法:

  1. 返回一个静态数组

    它解决了悬空指针问题,但会导致非线程安全函数

  2. 返回分配的数组

    它也解决了线程问题,但是:

    • 来电者必须处理免费电话
    • 分配真正的二维数组远非易事
  3. 让调用者提供数组及其大小

    这样调用者就可以完全控制内存的种类(自动、静态或动态),并且如果您还传递了它们的维度,您就可以轻松地使用多维数组。

顺便说一句,您不能将char ** 用于二维数组。二维数组和指针数组是 C 语言中非常不同的对象。阅读this了解更多详情...

【讨论】:

【解决方案2】:

在您的代码中,您返回局部变量。这是个坏主意,因为在这个函数之外,ipv4 可能不存在。

您可以将ip4 定义为指向指针的指针,然后为其分配。

char **ipv4 = malloc(sizeof(char *)*4); // that is allocation  for 4 pointer size.
if(!ipv4) {return NULL;} // exit function if you are failed to allocate for `ipv4`

另一件事,在您的代码中,您使用:

*ipv4 [i]=strtok(ch, ".");

应该是

ipv4 [i]=strtok(ch, ".");

因为,strtok 返回字符串值/指向字符 (char *) 的指针不是字符。

while 循环应该为i 添加条件:

while (ipv4 [i]!= NULL && i < 4) {

因为我们为ip4分配了4个指针。

您也可以将ipv4 作为函数的参数传递,然后不返回任何内容:

void extraction_ip(char **ipv4, char **ip) {}

您可以在以下位置查看更多信息:Returning a 2D char array in C

How to return a 2D array to a function in C?

【讨论】:

  • 我尝试先进行 void extract_ip(char **ipv4, char **ip) {},但在编译过程中出现了一些错误。我有这个:media.discordapp.net/attachments/620604126694342688/…
  • 将主要的ipv4 更改为char **ipv4char *ipv4[4]。或者将函数extraction_ip的声明改为char ipv[4][3]ipv[][3]
【解决方案3】:

您应该动态创建 ipv4 数组,因为它是本地的。

char **ipv4 =( int**)malloc(sizeof (char*)*4);

用于分配 4 行。

ipv4[i]=(char*)malloc(sizeof(char)*3);

用于在每个“i”行中分配 3 列。

因此我们创建了 ipv4 [4][3]。就这样回来了

return ipv4

【讨论】:

    最近更新 更多