代码之家  ›  专栏  ›  技术社区  ›  Alex Alifimoff

无效读数-Valgrind和C

  •  1
  • Alex Alifimoff  · 技术社区  · 10 年前

    刚接触C和Valgrind以及手动内存管理,我很难找到运行Valgrind时遇到的错误。我有一个从用户获取字符串的函数:

    char **get_fragments_from_user(){
        // No more than 20k strings containing at most 1k characters
        char **strings = malloc(20000 * sizeof(char *));
    
        char tempstring[MAX_INPUT]; //MAX_INPUT = 1001
        int count = 0;
        while(true){
            printf("\n> ");
            fgets(tempstring, MAX_INPUT, stdin);
            if((strlen(tempstring) > 0) && (tempstring[strlen(tempstring) - 1] == '\n')){
                tempstring[strlen(tempstring) - 1] = '\0';
            }
            if(tempstring[0] == 'q') break;
            strings[count] = malloc(sizeof(char) * (strlen(tempstring)+1));
            strcpy(strings[count], tempstring);
            count++;
        }
        int i = 0;
        char **fstrings = malloc((count)*sizeof(char *)); // count+1 needed? Something I tried removing while debugging
        for(i = 0; i < count; i++){
            fstrings[i] = malloc(sizeof(char) * (strlen(strings[i])+1));
            strcpy(fstrings[i], strings[i]);
            free(strings[i]);
        }
        free(strings);
        return fstrings;
    }
    

    这里的想法是简单地获取字符串并将其放入数组中。最初,我分配了一个足够大的数组,以容纳可以输入的最大字符串数(20000),但随后我调整了数组的大小,这样我就不会分配比每个字符串所需的内存更多的内存。我对上面的代码有点不好意思,因为它比我用另一种语言编写的任何代码都不干净,但这是我第一次通过。

    然后,当我尝试使用此函数计算数组中的字符串数时,我从Valgrind得到“无效读取大小为8”:

    int lengthOf(char **arr){
        int i = 0;
        while(arr[i] != NULL){
            i++;
        }
        return i;
    }
    

    我很确定这是由于取消引用的指针或其他原因,但我一辈子都找不到它,我已经看了一个小时左右的代码。

    1 回复  |  直到 10 年前
        1
  •  0
  •   Alex Alifimoff    9 年前

    所以,我认为问题是我没有分配足够的内存来存储整个阵列。

    而不是:

    malloc(count * sizeof(char *));
    

    我应该分配count+1,所以:

    malloc((count + 1) * sizeof(char *))
    

    calloc((count + 1), sizeof(char *));