【问题标题】:How to dynamically allocate memory for char** in C如何在C中为char**动态分配内存
【发布时间】:2013-01-25 00:49:42
【问题描述】:

如何在这个函数中为 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++;
        }
    }
}

【问题讨论】:

    标签: c arrays c-strings dynamic-allocation


    【解决方案1】:

    这样做:

    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() 到第一个字符。

    尝试:

    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));  
    

    【讨论】:

    • 试过了,我遇到了段错误。我将编辑我的代码以展示我是如何实现它的。感谢您的快速回复
    • 我分配了 wordLine 和 counter 的值,但仍然无法正常工作。
    • @CarlosCarrillo 现在有什么问题。在malloc() 之前打印您的wordLine and counter 以检查值。
    • 如果我没有提前知道 wordline?我是否必须切换到使用链表,链表中的每个节点都代表一个单词?
    • @viki.omega9 如果你无法计算出你需要多大的尺寸,那么你有两个 approcahis (1) void* realloc (void* ptr, size_t size); (2) 链表
    【解决方案2】:

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

    这样,你的单词在内存中是一个连续的块,你不必关心文件 I/O,因为你在内存中有整个文本文件为 char*,而你没有分配一个数组数组。

    有关函数的信息,请参阅相应的手册页,或给我留言:)

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

    如今,大多数 C 程序员仍然尝试使用 fopen 和朋友将文件读入内存,但这完全没有必要,并且会带来额外的复杂性。 (缓冲,增长的数组,...)和mmap 是一个不错的选择,可以将所有讨厌的工作转移到操作系统

    【讨论】:

      猜你喜欢
      • 2015-08-09
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      • 2017-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      相关资源
      最近更新 更多