简体   繁体   English

在c中动态分配我的2d数组

[英]dynamically allocating my 2d array in c

Any hints on how I would dynamically allocate myArray so I can enter any amount of strings and it would store correctly. 有关如何动态分配myArray任何提示,以便我可以输入任意数量的字符串,它将正确存储。

int main()
{

char myArray[1][1]; //how to dynamically allocate the memory?
counter = 0;
char *readLine;
char *word;
char *rest;

printf("\n enter: ");
ssize_t buffSize = 0;
getline(&readLine, &buffSize, stdin);//get user input 

//tokenize the strings
while(word = strtok_r(readLine, " \n", &rest )) {

            strcpy(myArray[counter], word);
            counter++;
            readLine= rest;
}

//print the elements user has entered 
int i =0;
for(i = 0;i<counter;i++){
    printf("%s ",myArray[i]);
}
printf("\n");

}

Use realloc like this: 像这样使用realloc:

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

int main(void){
    char **myArray = NULL;
    char *readLine = NULL;
    size_t buffSize = 0;
    size_t counter = 0;
    char *word, *rest, *p;

    printf("\n enter: ");
    getline(&readLine, &buffSize, stdin);
    p = readLine;
    while(word = strtok_r(p, " \n", &rest )) {
        myArray = realloc(myArray, (counter + 1) * sizeof(*myArray));//check omitted
        myArray[counter++] = strdup(word);
        p = NULL;
    }
    free(readLine);
    for(int i = 0; i < counter; i++){
        printf("<%s> ", myArray[i]);
        free(myArray[i]);
    }
    printf("\n");
    free(myArray);
}

Here is one way you might approach this problem. 以下是解决此问题的一种方法。 If you are going to dynamically allocate storage for an unknown number of words of unknown length, you can start with a buffSize that seems reasonable, allocate that much space for the readLine buffer, and grow this memory as needed. 如果要为未知长度的未知数量的单词动态分配存储空间,可以从看似合理的buffSize开始,为readLine缓冲区分配那么多空间,并根据需要增加此内存。 Similarly, you can choose a reasonable size for the number of words expected, and grow word storage as needed. 同样,您可以为预期的单词数选择合理的大小,并根据需要增加单词存储。

In the program below, myArray is a pointer to pointer to char . 在下面的程序中, myArray是指向char指针。 arrSize is initialized so that pointers to 100 words may be stored in myArray . 初始化arrSize ,以便在myArray存储指向100个单词的指针。 First, readLine is filled with an input line. 首先, readLine填充输入行。 If more space than provided by the initial allocation is required, the memory is realloc ed to be twice as large. 如果需要比由初始分配提供更多的空间,该存储器是realloc ED是两倍大。 After reading in the line, the memory is again realloc ed to trim it to the size of the line (including space for the '\\0' ). 在线读取数据后,存储器再次是realloc ED将其修剪到行的大小(包括为空间'\\0' )。

strtok_r() breaks the line into tokens. strtok_r()将行拆分为标记。 The pointer store is used to hold the address of the memory allocated to hold the word, and then word is copied into this memory using strcpy() . 指针store区用于保存分配用于保存字的内存地址,然后使用strcpy()word复制到该内存中。 If more space is needed to store words, the memory pointed to by myArray is realloc ed and doubled in size. 如果需要更多的空间来存储字,所述存储器所指向的myArrayrealloc ED和大一倍。 After all words have been stored, myArray is realloc ed a final time to trim it to its minimum size. 所有词都被存储后, myArrayrealloc编最后一次给它修剪到它的最小尺寸。

When doing this much allocation, it is nice to write functions which allocate memory and check for errors, so that you don't have to do this manually every allocation. 在进行这么多分配时,编写分配内存和检查错误的函数是很好的,这样您就不必每次分配都手动执行此操作。 xmalloc() takes a size_t argument and an error message string. xmalloc()接受一个size_t参数和一个错误消息字符串。 If an allocation error occurs, the message is printed to stderr and the program exits. 如果发生分配错误,则将消息打印到stderr并退出程序。 Otherwise, a pointer to the allocated memory is returned. 否则,返回指向已分配内存的指针。 Similarly, xrealloc() takes a pointer to the memory to be reallocated, a size_t argument, and an error message string. 类似地, xrealloc()接受一个指向要重新分配的内存的指针,一个size_t参数和一个错误消息字符串。 Note here that realloc() can return a NULL pointer if there is an allocation error, so you need to assign the return value to a temporary pointer to avoid a memory leak. 请注意,如果存在分配错误, realloc()可以返回NULL指针,因此您需要将返回值分配给临时指针以避免内存泄漏。 Moving realloc() into a separate function helps protect you from this issue. realloc()移动到单独的函数中有助于保护您免受此问题的影响。 If you assigned the return value of realloc() directly to readLine , for example, and if there were an allocation error, readLine would no longer point to the previously allocated memory, which would be lost. 例如,如果您将realloc()的返回值直接分配给readLine ,并且如果存在分配错误,则readLine将不再指向先前分配的内存,该内存将丢失。 This function prints the error message and exits if there is an error. 此函数打印错误消息,并在出现错误时退出。

Also, you need to free all of these memory allocations, so this is done before the program exits. 此外,您需要free所有这些内存分配,因此这是在程序退出之前完成的。

This method is more efficient than realloc ing memory for every added character in the line, and for every added pointer to a word in myArray . 这种方法比更有效realloc在每行字符添加荷兰国际集团存储器,并且为每个添加的指针到一个字myArray With generous starting values for buffSize and arrSize , you may only need the initial allocations, which are then trimmed to final size. 使用buffSizearrSize ,您可能只需要初始分配,然后将其修剪为最终大小。 Of course, there are still the individual allocations for each of the individual words. 当然,每个单词仍然有单独的分配。 You could also use strdup() for this part, but you would still need to remember to free those allocations as well.Still, not nearly as many allocations will be needed as when readLine and myArray are grown one char or one pointer at a time. 你也可以在这部分使用strdup() ,但是你仍然需要记住释放那些分配。但是,当readLinemyArray增长一个char或一个指针时,将不需要那么多的分配。

#define _POSIX_C_SOURCE 1

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

void * xmalloc(size_t size, char *msg);
void * xrealloc(void *ptr, size_t size, char *msg);

int main(void)
{

    char **myArray;
    size_t buffSize = 1000;
    size_t arrSize = 100;
    size_t charIndex = 0;
    size_t wordIndex = 0;
    char *readLine;
    char *inLine;
    char *word;
    char *rest;
    char *store;

    /* Initial allocations */
    readLine = xmalloc(buffSize, "Allocation error: readLine");
    myArray = xmalloc(sizeof(*myArray) * arrSize,
                      "Allocation error: myArray\n");

    /* Get user input */    
    printf("\n enter a line of input:\n");

    int c;
    while ((c = getchar()) != '\n' && c != EOF) {
        if (charIndex + 1 >= buffSize) {      // keep room for '\0'
            buffSize *= 2;
            readLine = xrealloc(readLine, buffSize,
                                "Error in readLine realloc()\n");
        }
        readLine[charIndex++] = c;
    }
    readLine[charIndex] = '\0';             // add '\0' terminator

    /* If you must, trim the allocation now */
    readLine = xrealloc(readLine, strlen(readLine) + 1,
                       "Error in readLine trim\n");

    /* Tokenize readLine */
    inLine = readLine;
    while((word = strtok_r(inLine, " \n", &rest)) != NULL) {
        store = xmalloc(strlen(word) + 1, "Error in word allocation\n");
        strcpy(store, word);

        if (wordIndex >= arrSize) {
            arrSize *= 2;
            myArray = xrealloc(myArray, sizeof(*myArray) * arrSize,
                               "Error in myArray realloc()\n");
        }   
        myArray[wordIndex] = store;
        wordIndex++;
        inLine = NULL;
    }

    /* You can trim this allocation, too */
    myArray = xrealloc(myArray, sizeof(*myArray) * wordIndex,
                      "Error in myArray trim\n");

    /* Print words */
    for(size_t i = 0; i < wordIndex; i++){
        printf("%s ",myArray[i]);
    }
    printf("\n");

    /* Free allocated memory */
    for (size_t i = 0; i < wordIndex; i++) {
        free(myArray[i]);
    }
    free(myArray);
    free(readLine);

    return 0;
}

void * xmalloc(size_t size, char *msg)
{
    void *temp = malloc(size);
    if (temp == NULL) {
        fprintf(stderr, "%s\n", msg);
        exit(EXIT_FAILURE);
    }
    return temp;
}

void * xrealloc(void *ptr, size_t size, char *msg)
{
    void *temp = realloc(ptr, size);
    if (temp == NULL) {
        fprintf(stderr, "%s\n", msg);
        exit(EXIT_FAILURE);
    }
    return temp;
}

I suggest you first scan the data and then call malloc() with the appropriate size. 我建议你首先扫描数据,然后调用具有适当大小的malloc() Otherwise, you can use realloc() to reallocate memory as you go through the data. 否则,您可以使用realloc()在浏览数据时重新分配内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM