【问题标题】:Mallocing a char **?分配一个字符**?
【发布时间】:2014-06-20 21:03:59
【问题描述】:

我正在编写代码以保存我将在 char *tmp 中读取的内容(get_next_line 的返回是 char *,在 fd 0 上读取) get_next_line 为 char *tmp 分配正确的空间。

所以我将 tmp 保存在 data[i] 中,这是一个 char **,以便将所有输入都保存在 char **data 中。

但我需要 malloc 一个 char **data 但我不知道我需要什么大小。

这段代码有效,但它是 Segfault,因为我没有 malloc char **data。

我知道如何分配一个 char **,但在这里我不知道如何分配它,因为大小不是恒定的。

代码如下:

#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>

int redirection(char *prev, char *next) {
    int b;
    char *tmp;
    char **data;
    int i;

    i = 0;
    b = 0;
    while (b != 1) {
        while (strcmp(next, tmp) != 0) {
            printf("> ");
            tmp = get_next_line(0);
            data[i++] = tmp;
        }
        data[--i] = 0;
        i = 0;
        while (data[i] != 0)
           printf("DATA = [%s]\n, data[i++]");
        b = 1;
    }
    free(tmp);
    return (0);
  }

这是测试的主要内容:

int main(int ac, char **av) {
    if ((redirection("START", "STOP")) == -1) {
         printf("REDIRECTION FAIL\n");
         return(-1):
    }
    return(0);
}

【问题讨论】:

  • get_next_line 是否分配空间?
  • 是的,get_next_line完美的为char *tmp分配了正确的空间,没有问题。
  • get_next_line 是什么样子的?
  • char *get_next_line(const int fd) ... ... ... 返回一个 char * malloced 并在 fd 0 上读取直到 '\n'。
  • get_next_line 是否在任何时候都返回 NULL,因为您的逻辑似乎假设了这一点?

标签: c pointers char malloc


【解决方案1】:

char** 是“指向 char* 的指针”。

你必须得到一个结构链接:

char** [_] ----- > char* |_| ----> [__________]  <-- this is M * sizeof(char)
                   char* |_| ----> [__________]
                   char* |_| ----> [__________]
                   char* |_| ----> [__________]
                   char* |_| ----> [__________]
                   char* |_| ----> [__________]
                          ^                   ^
                          |                   \-- this is just char
                  This is N*sizof(char*)

【讨论】:

    【解决方案2】:

    我想你要找的是realloc()

    当您达到分配的指针限制时,您可以添加更多指针。

    例如

    size_t rows = 10;
    
    char**  data = malloc( sizeof(char*) * rows );
    size_t row = 0;
    
    ...
    
    tmp = get_next_line(0);
    
    if ( ++row == rows )
    {
      row = 0;
      rows += 10;
      char** expanded = realloc( data, sizeof(char*) * rows );
      if ( expanded != NULL )
      {
        data = expanded;
      }
      // else error
    }
    
    data[i++] = tmp;
    
    ...
    

    附注:

    看起来你覆盖了最后一个字符串

    while (b != 1) {
        while (strcmp(next, tmp) != 0) {
            printf("> ");
            tmp = get_next_line(0);
            data[i++] = tmp;
        }
        data[--i] = 0; <---- maybe you meant `data[i]=NULL;`
    

    【讨论】:

      【解决方案3】:

      这是 malloc **数据的方法:

      #define NUMBER_OF_ROWS      10
      #define NUMBER_OF_COLUMNS   20
      
      data = malloc(NUMBER_OF_ROWS * sizeof(char*));
      for (i = 0; i < NUMBER_OF_ROWS; i++)
      {
        data[i] = malloc(NUMBER_OF_COLUMNS * sizeof(char));
      }
      

      您应该在分配内存时释放内存。

      【讨论】:

      • 好的,谢谢。我已经知道了 ^^" 但问题是我不知道 "NUMBER_OF_ROWS" 和 NUMBER_OF_COLLUMNS"。我的行是我将在 0 上读取的每个输入。我的列是我将在 0 上读取的一个输入的每个字符。
      【解决方案4】:

      欢迎来到手动分配的世界!如果你想分配自己的缓冲区,必须知道你可以用它们做什么......并尽快释放它们......

      这里有一些我已经根据问题使用过的可能性:

      • 两遍方法:在第一遍时,您不分配任何东西,而只是简单地计算您将拥有多少个元素:非常简单,在空间上有效,但在时间上没有。如果您正在读取流而不是文件,请不要考虑这一点...
      • 高最大值方法:如果您可以提前知道您将永远不会超过 xxx 个元素,请分配一个大小为 xxx 的缓冲区...并确认程序不会进一步!如果是这样,您至少应该输出一条友好的消息来解释正在发生的事情 - 快速简单但不是真正的防弹(如果您在现实世界中尝试过这种方法,您应该允许用户自定义您的最大值,但它可以处理流量吗? )
      • 链式缓冲区方法:首先分配一个大小为 n 的缓冲区(通常 n 介于 16 和 1024 之间),然后在用尽时分配另一个缓冲区。实际上,您应该分配一个

        struct Buff {
            struct Buff* next;
            int nElts;
            char **elts; /* in fact enough size for nElts char pointers */
        }
        

        您可以分配相同大小的缓冲区,或者在每次迭代时将大小加倍,具体取决于您是否知道必须管理的元素的实际数量。这个既节省时间又节省空间,但它不再简单,因为将不得不管理不同缓冲区上的指针运算。

      如果这些方法都不符合您的要求,您还可以查看标准 C++ 库或 Boost,其中已经编写了有效的算法......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-09-22
        • 2015-05-20
        • 2016-05-15
        • 1970-01-01
        • 2021-03-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多