[英]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. 如果需要更多的空间来存储字,所述存储器所指向的
myArray
是realloc
ED和大一倍。 After all words have been stored, myArray
is realloc
ed a final time to trim it to its minimum size. 所有词都被存储后,
myArray
是realloc
编最后一次给它修剪到它的最小尺寸。
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. 使用
buffSize
和arrSize
,您可能只需要初始分配,然后将其修剪为最终大小。 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()
,但是你仍然需要记住释放那些分配。但是,当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;
}
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.