[英]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
復制到該內存中。 如果需要更多的空間來存儲字,所述存儲器所指向的myArray
是realloc
ED和大一倍。 所有詞都被存儲后, myArray
是realloc
編最后一次給它修剪到它的最小尺寸。
在進行這么多分配時,編寫分配內存和檢查錯誤的函數是很好的,這樣您就不必每次分配都手動執行此操作。 xmalloc()
接受一個size_t
參數和一個錯誤消息字符串。 如果發生分配錯誤,則將消息打印到stderr
並退出程序。 否則,返回指向已分配內存的指針。 類似地, xrealloc()
接受一個指向要重新分配的內存的指針,一個size_t
參數和一個錯誤消息字符串。 請注意,如果存在分配錯誤, realloc()
可以返回NULL
指針,因此您需要將返回值分配給臨時指針以避免內存泄漏。 將realloc()
移動到單獨的函數中有助於保護您免受此問題的影響。 例如,如果您將realloc()
的返回值直接分配給readLine
,並且如果存在分配錯誤,則readLine
將不再指向先前分配的內存,該內存將丟失。 此函數打印錯誤消息,並在出現錯誤時退出。
此外,您需要free
所有這些內存分配,因此這是在程序退出之前完成的。
這種方法比更有效realloc
在每行字符添加荷蘭國際集團存儲器,並且為每個添加的指針到一個字myArray
。 使用buffSize
和arrSize
,您可能只需要初始分配,然后將其修剪為最終大小。 當然,每個單詞仍然有單獨的分配。 你也可以在這部分使用strdup()
,但是你仍然需要記住釋放那些分配。但是,當readLine
和myArray
增長一個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.