关注char **?

时间:2014-05-04 14:51:58

标签: c pointers char malloc

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

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

但我需要malloc一个char **数据,但我不知道我需要什么尺寸。

此代码有效,但它是Segfault,因为我没有使用malloc char **数据。

我知道如何对一个char **进行malloc,但在这里我不知道如何对它进行mallocate,因为它的大小不是常数。

以下是代码:

#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);
}

4 个答案:

答案 0 :(得分:2)

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

你必须得到的是这样的结构:

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

答案 1 :(得分:1)

我认为你要找的是realloc()

当你达到指定限制时,可以添加更多指针。

e.g。

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;`

答案 2 :(得分:0)

这是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));
}

你应该在编辑它时释放记忆。

答案 3 :(得分:0)

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

以下是我已经根据问题使用的一些可能性:

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

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

    您可以分配相同大小的缓冲区,或者在每次迭代时将大小增加一倍,具体取决于您是否了解必须管理的实际元素数。这个时间和空间效率都很高,但它不再简单,因为必须管理不同缓冲区的指针算法。

如果这些方法都不同意你,你也可以看一下标准的C ++库或Boost,其中有效的算法已经编码了......