【问题标题】:Allocate a 3D char array in C (char ***)在 C 中分配一个 3D char 数组(char ***)
【发布时间】:2013-07-05 12:50:34
【问题描述】:

我想分配一个char***。 我有一个这样的句子:“这是我||需要的命令&&;拆分” 我需要在每个框中输入一个完整的句子,就像这样:

cmd[0] = "This is a command"
cmd[1] = "wich I"
cmd[2] = "need to"
cmd[3] = "split"

句子由&&, ||, ;, | 等标记分隔。
我的问题是我不知道如何分配我的三维数组。 我总是遇到分段错误。

这就是我的工作:

for(k = 0; k < 1024; k++)
   for( j = 0; j < 1024; j++)
       cmd[k][j] = malloc(1024);

但是几行之后,在另一个循环中:

»           cmd[k][l] = array[i];

我在这里遇到了段错误。

请问我该怎么做? 提前致谢

【问题讨论】:

  • 将一个字符串拆分成多个子字符串只需要一个字符串数组,不是3D结构。
  • 你为什么想要 3D? char *arr[4] 将解决您的问题。要标记您的字符串,您可能需要调用strtok
  • 我只是在发布的代码中记录了一些内容,希望能够阐明它是如何出错的。对于那个分配循环,我假设 cmd 被声明为“char* cmd[1024][1024];”之类的东西,否则它就无法工作(它可能会编译,但取决于你所做的,甚至在分配期间可能不会出现段错误'ing)。当您执行“稍后几行”时,数组应该类似于“char* array[SOME_SIZE];”或“字符数组[SOME_SIZE0][SOME_SIZE1];”所以你在那里分配兼容的指针。即使那样,你也在那里泄漏内存。

标签: c arrays malloc allocation


【解决方案1】:

请记住,C 中的 2/3D 数组与 char *** 不同。

如果你只想拥有一个 1024^3 字符数组,那么你会很好

char array[1024][1024][1024];

但请记住,这将在您的堆栈上分配 1 GB 的空间,这可能会或可能不会工作。

要在堆上分配这么多,您需要正确输入:

char (*array)[1024][1024] = malloc(1024*1024*1024);

在这种情况下,array 是一个指向 2D 1024x1024 字符矩阵数组的指针。

如果您真的想使用char ***(如果您的数组长度是静态的,我不建议这样做),那么您也需要分配所有中间数组:

char *** cmd = malloc(sizeof(char **) * 1024);
for(k = 0; k < 1024; k++) {
    cmd[k] = malloc(sizeof(char *) * 1024);
    for( j = 0; j < 1024; j++)
           cmd[k][j] = malloc(1024);
}

【讨论】:

  • 感谢您的回答。好的,我认为这不是正确的方法。在不使用 strtok 的情况下,将我的字符串拆分为由标记分隔的字符串数组的最佳方法是什么?
  • @user2145240 由于您要通过比单个字符更长的分隔符进行拆分,因此我不确定是否有更好的方法来执行此操作,然后通过子字符串搜索每个分隔符。请参阅我的其他答案以获取建议。
【解决方案2】:

如果您要通过比单个字符更长的分隔符来分割字符串,那么您可以通过字符串搜索来做到这一点。

以下函数将接受输入字符串和分隔符字符串。 它会返回一个char **,它必须是freed,它会破坏你的输入字符串(重用它的内存来存储令牌)。

char ** split_string(char * input, const char * delim) {
    size_t num_tokens = 0;
    size_t token_memory = 16; // initialize memory initially for 16 tokens
    char ** tokens = malloc(token_memory * sizeof(char *));

    char * found;
    while ((found = strstr(input, delim))) { // while a delimiter is found
        if (input != found) { // if the strind does not start with a delimiter

            if (num_tokens == token_memory) { // increase the memory array if it is too small
                void * tmp = realloc(tokens, (token_memory *= 2) * sizeof(char *));
                if (!tmp) {
                    perror("realloc"); // out of memory
                }
                tokens = tmp;
            }

            tokens[num_tokens++] = input;
            *found = '\0';
        }
        // trim off the processed part of the string
        input = found + strlen(delim);
    }

    void * tmp = realloc(tokens, (num_tokens +1) * sizeof(char *));
    if (!tmp) {
        perror("realloc"); // something weird happened
    }
    tokens = tmp;

    // this is so that you can count the amount of tokens you got back
    tokens[num_tokens] = NULL;

    return tokens;
}

您将需要递归地运行它来分割多个分隔符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    相关资源
    最近更新 更多