如何在C中为char **动态分配内存

时间:2013-02-09 08:45:00

标签: c arrays c-strings dynamic-allocation

如何在此函数中动态分配内存到char **列表?

基本上这个程序的想法是我必须从文件中的单词列表中读取。我不能假设最大字符串或最大字符串长度。

我必须用C字符串做其他事情,但那些东西我应该没问题。

谢谢!

void readFileAndReplace(int argc, char** argv)
{
    FILE *myFile;
    char** list;
    char c;
    int wordLine = 0, counter = 0, i;
    int maxNumberOfChars = 0, numberOfLines = 0, numberOfChars = 0;

    myFile = fopen(argv[1], "r");

    if(!myFile)
    {
        printf("No such file or directory\n");
        exit(EXIT_FAILURE);
    }

    while((c = fgetc(myFile)) !=EOF)
    {
        numberOfChars++;
        if(c == '\n')
        {
            if(maxNumberOfChars < numberOfChars)
                maxNumberOfChars += numberOfChars + 1;

            numberOfLines++;
        }
    }

    list = malloc(sizeof(char*)*numberOfLines);

    for(i = 0; i < wordLine ; i++)
        list[i] = malloc(sizeof(char)*maxNumberOfChars);


    while((c = fgetc(myFile)) != EOF)
    {
        if(c == '\n' && counter > 0)
        {
            list[wordLine][counter] = '\0';
            wordLine++;
            counter = 0;
        }
        else if(c != '\n')
        {
            list[wordLine][counter] = c;
            counter++;
        }
    }
}

2 个答案:

答案 0 :(得分:6)

这样做:

char** list; 

list = malloc(sizeof(char*)*number_of_row);
for(i=0;i<number_of_row; i++) 
  list[i] = malloc(sizeof(char)*number_of_col);  

此外,如果您要动态分配内存。你要把它当作工作来解放它:

for(i=0;i<number_of_row; i++) 
  free(list[i] );
free(list);  

编辑

在你修改过的问题中:

 int wordLine = 0, counter = 0, i;    

wordLinecounter0

在此代码之前

list = malloc(sizeof(char*)*wordLine+1);
for(i = 0;i < wordLine ; i++)
   list[i] = malloc(sizeof(char)*counter);  

您必须为wordLinecounter变量

分配值

内存分配也应该在以下循环之前(外部):

 while((c = fgetc(myFile)) != EOF){
  :
  :
 }

编辑

新问题的第三个版本。你正在读两次文件。因此,在第二次循环开始之前,您需要fseek(), rewind()到第一个char。

尝试:

fseek(fp, 0, SEEK_SET); // same as rewind()
rewind(fp);             // same as fseek(fp, 0, SEEK_SET)

我也怀疑你的逻辑是numberOfLinesmaxNumberOfChars。请检查

编辑

我认为你对maxNumberOfChars = 0, numberOfLines = 0的计算是错误的尝试如下:

maxNumberOfChars = 0, numberOfLines = 0, numberOfChars = 0;
while((c = fgetc(myFile)) !=EOF){
     if(c == '\n'){
         numberOfLines++; 
         if(maxNumberOfChars < numberOfChars)
             maxNumberOfChars = numberOfChars;
         numberOfChars=0
     }
     numberOfChars++;
}    

maxNumberOfChars是一行中最大字符数。

同时更改代码:

malloc(sizeof(char)*(maxNumberOfChars + 1));  

答案 1 :(得分:1)

如果我是你,我会使用mmap将文件映射到私有内存,然后遍历文件,在char**数组中存储单词的开头,您可以将其添加为你选择realloc,用0替换换行符。

这样,你把你的单词作为一个连续的块存储在内存中,你不必关心文件I / O,因为你将整个文本文件作为char*存储在内存中,并且你不要必须malloc一个数组数组。

有关这些功能的信息,请参阅相应的手册页,或发表评论:)

编辑:如果你还不知道mmap,请看一下:http://www.jimscode.ca/index.php/component/content/article/13-c/45-c-simple-mmap-example

今天大多数C程序员仍尝试使用fopen和朋友将文件读入内存,但这完全没有必要,并引入了附加级别的复杂性。 (缓冲,增长数组,......)和mmap是一个很好的选择,可以将所有令人讨厌的工作转移到操作系统