C - 动态调整二维char数组的大小

时间:2015-11-20 12:08:38

标签: c arrays dynamic multidimensional-array

大家好,你们需要你的专业知识!

正如标题所揭示的那样,我希望调整2 dim的大小。 C中的char array我已经知道如何使用更简单的“数据结构:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main( void ){
    int *store;
    int capacity = 3;
    store = malloc(capacity * sizeof(int));
    store[0] = 0;
    store[1] = 1;
    store[2] = 2;

    /* need more storage */

    int new_capacity = 5;
    int *more_storage = realloc(store, new_capacity);
    more_storage = store;

    more_storage[3] = 3;
    more_storage[4] = 4;
    // Is this free() command dangerous? 
    free(store);
    /* this for loop gives me the correct integers, so i can proof that more_storage indeed contains all the
    values, that have been stored in store*/
    for (int i = 0; i < new_capacity; i++){
        printf("%d\n", more_storage[i]);
    }

    /* I have succesfully created a new array, that contains all the old integers plus 
    the new ones */ 

    return 0;
}

现在让我们来看看热门话题: 再做同样的事情,只有一个char数组,存储一个未知数量的字符串,最大长度为100(或其他):

char [???][100];

尽管你们中的一些人可能摇头,但我发布了我的 接近它:(善待,我是一个初学者:P)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main( void ){
    //this means to be the 2 - dim array. not sure, if i'm wrong yet.
    char *store[100];
    int capacity = 3;
    store[100] = malloc(capacity * 100 * sizeof(char));
    // This (below) already causes a segmentation fault... :/ 
    strcpy(store[0], "Hi");

    /*Okai, im done yet.. */ 



}

这里有一种方法,可能对你的娱乐有用:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main( void ){
    char **store;
    int capacity_words = 3;
    int capacity_letters = 100;
    /* Means: char store[3][100]*/

    store = malloc(capacity_words * capacity_letters *sizeof(char));
    strcpy(store[0], "Hi");
    //Segmentation fault again..
    // Damn..! Programming is hard..:D 

}

Okai这是我的知识基准,任何人都可以与我分享他或她的答案吗? :)

(我更加详细和普遍,因为我希望这也可以作为任何其他艺术学者的答案。)

3 个答案:

答案 0 :(得分:2)

可以使用一维数组作为二维数组,但对于像字符串这样的可变长度数据,它的工作量超过了它的价值。如果你这样做,你需要一个指针,而不是指向指针的指针。

对于字符串,您需要分配一个指针数组,例如

char **store = malloc(initial_size * sizeof(*store));

for (size_t i = 0; i < initial_size; ++i)
    store[i] = some_string;  // alternatively strdup(some_string) or similar

然后当你需要重新分配这个数组时,就像你对一维数组一样:

char **new_store = realloc(store, new_size * sizeof(*new_store));
if (new_store == NULL)
{
    fprintf(stderr, "Error reallocating memory\n");
    exit(EXIT_FAILURE);
}
store = new_store;

for (size_t i = initial_size; i < new_size; ++i)
    store[i] = ...; // Initialize new memory

答案 1 :(得分:2)

代码1)你不应该释放(存储) - 它已经被前面的realloc释放或者等于new_storage(如果realloc认为旧的块还适合新的大小)。

代码2)数组被放入堆栈中,没有选项可以在不破坏堆栈的情况下增长。

代码3)这是非常合理的,但请注意,您不仅要分配数组本身(外部维度),还要分配每个内部维度(capacity_word乘以字符串)。 strncpy在这里不可用,因为store [0]尚未初始化;相反,试试

store[0] = strdup("Hi");
store[1] = strdup("There");
store[2] = strdup("!");

答案 2 :(得分:2)

定义

char *store[100];

创建一个包含100个字符指针的数组。您可以将现有字符串分配给这些指针,也许是通过strdup获得的字符串,但您不能strcpy给它们,因为它们未初始化且不指向任何合理的位置。

您可以使用以下命令创建指向100个字符数组的指针:

char (*store)[100];

现在你可以将momory分配给该指针并使用它:

int capacity = 3;

store = malloc(capacity * sizeof(*store));
strcpy(store[0], "orange");
strcpy(store[1], "green");
strcpy(store[2], "mauve");

重新分配同样有效:

capacity = 5;
store = realloc(store, capacity * sizeof(*store));

store[3] = 3;
store[4] = 4;

(我已将新内存分配给相同的空间,这通常是您想要的。如果重新分配失败,这将失去原始数据。请参阅Joachim的示例,了解如何处理该情况。)

当然,您应该在使用后释放已分配的内存:

for (int i = 0; i < capacity; i++) puts(store[i]);

free(store);

这种方法既浪费又有限制,因为你为短字符串浪费了大量空间,但仍然限制在99个字符以内。根据您的需求分配内存可能会更好。 (但至少这种方法可以立即为每个字符串提供100个字符。唯一的分配和释放是store正确的。)