簡體   English   中英

在c中動態分配我的2d數組

[英]dynamically allocating my 2d array in c

有關如何動態分配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");

}

像這樣使用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);
}

以下是解決此問題的一種方法。 如果要為未知長度的未知數量的單詞動態分配存儲空間,可以從看似合理的buffSize開始,為readLine緩沖區分配那么多空間,並根據需要增加此內存。 同樣,您可以為預期的單詞數選擇合理的大小,並根據需要增加單詞存儲。

在下面的程序中, myArray是指向char指針。 初始化arrSize ,以便在myArray存儲指向100個單詞的指針。 首先, readLine填充輸入行。 如果需要比由初始分配提供更多的空間,該存儲器是realloc ED是兩倍大。 在線讀取數據后,存儲器再次是realloc ED將其修剪到行的大小(包括為空間'\\0' )。

strtok_r()將行拆分為標記。 指針store區用於保存分配用於保存字的內存地址,然后使用strcpy()word復制到該內存中。 如果需要更多的空間來存儲字,所述存儲器所指向的myArrayrealloc ED和大一倍。 所有詞都被存儲后, myArrayrealloc編最后一次給它修剪到它的最小尺寸。

在進行這么多分配時,編寫分配內存和檢查錯誤的函數是很好的,這樣您就不必每次分配都手動執行此操作。 xmalloc()接受一個size_t參數和一個錯誤消息字符串。 如果發生分配錯誤,則將消息打印到stderr並退出程序。 否則,返回指向已分配內存的指針。 類似地, xrealloc()接受一個指向要重新分配的內存的指針,一個size_t參數和一個錯誤消息字符串。 請注意,如果存在分配錯誤, realloc()可以返回NULL指針,因此您需要將返回值分配給臨時指針以避免內存泄漏。 realloc()移動到單獨的函數中有助於保護您免受此問題的影響。 例如,如果您將realloc()的返回值直接分配給readLine ,並且如果存在分配錯誤,則readLine將不再指向先前分配的內存,該內存將丟失。 此函數打印錯誤消息,並在出現錯誤時退出。

此外,您需要free所有這些內存分配,因此這是在程序退出之前完成的。

這種方法比更有效realloc在每行字符添加荷蘭國際集團存儲器,並且為每個添加的指針到一個字myArray 使用buffSizearrSize ,您可能只需要初始分配,然后將其修剪為最終大小。 當然,每個單詞仍然有單獨的分配。 你也可以在這部分使用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;
}

我建議你首先掃描數據,然后調用具有適當大小的malloc() 否則,您可以使用realloc()在瀏覽數據時重新分配內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM