C - Freeing Malloc.运行时出错

45a*_*ken 0 c malloc

我不知道我的程序有什么问题.我使用一个循环使用malloc分配内存,当我去释放它时,它给了我以下错误:

"*** glibc detected *** ./assignment4: free(): invalid pointer: 0x08eeb196 ***
Run Code Online (Sandbox Code Playgroud)

该错误伴随着具有标题存储器映射的列表.循环从1到7运行.奇怪的是当我释放[0]字符串的值时,我没有得到任何错误.该错误只与我尝试释放上来[1][7]其使用循环malloced.

void lineParse()
{
    int i;
    FILE *fp;
    fp = fopen("specification.txt", "r");

    char ** listofdetails; 
    listofdetails = malloc(sizeof(char*)*6);

    for(i=0;i<6;i++)
    {
        listofdetails[i] = malloc(sizeof(char)*40);
        fgets(listofdetails[i], 40, fp);
        /*printf("%s \n", listofdetails[i]);*/
        /*free(listofdetails[i]);*/
    }


    char ** stringOne; 
    stringOne = malloc(sizeof(char*)*8);

    stringOne[0] = malloc(sizeof(char)*6);
    stringOne[0] = strtok(listofdetails[0], " ");

    for(i=1;i<8;i++)
    {
        stringOne[i] = malloc(sizeof(char)*6);
        stringOne[i] = strtok(NULL, " ");
    }

    char ** stringTwo; 
    stringTwo = malloc(sizeof(char*)*8);

    stringTwo[0] = malloc(sizeof(char)*6);
    stringTwo[0] = strtok(listofdetails[1], " ");

    for(i=1;i<8;i++)
    {
        stringTwo[i] = malloc(sizeof(char)*6);
        stringTwo[i] = strtok(NULL, " ");
    }

    char ** stringThree; 
    stringThree = malloc(sizeof(char*)*8);

    stringThree[0] = malloc(sizeof(char)*6);
    stringThree[0] = strtok(listofdetails[2], " ");

    for(i=1;i<8;i++)
    {
        stringThree[i] = malloc(sizeof(char)*6);
        stringThree[i] = strtok(NULL, " ");
    }

    char ** stringFour; 
    stringFour= malloc(sizeof(char*)*8);

    stringFour[0] = malloc(sizeof(char)*6);
    stringFour[0] = strtok(listofdetails[3], " ");

    for(i=1;i<8;i++)
    {
        stringFour[i] = malloc(sizeof(char)*6);
        stringFour[i] = strtok(NULL, " ");
    }

    char ** stringFive; 
    stringFive= malloc(sizeof(char*)*8);

    stringFive[0] = malloc(sizeof(char)*6);
    stringFive[0] = strtok(listofdetails[4], " ");

    for(i=1;i<8;i++)
    {
        stringFive[i] = malloc(sizeof(char)*6);
        stringFive[i] = strtok(NULL, " ");
    }

    char ** stringSix; 
    stringSix= malloc(sizeof(char*)*8);

    stringSix[0] = malloc(sizeof(char)*6);
    stringSix[0] = strtok(listofdetails[5], " ");

    for(i=1;i<8;i++)
    {
        stringSix[i] = malloc(sizeof(char)*6);
        stringSix[i] = strtok(NULL, " ");
    }

    printf(" %s \n", stringSixrows);*/

    { //This works fine
        free(stringOne[0]);
        free(stringTwo[0]);
        free(stringThree[0]);
        free(stringFour[0]);
        free(stringFive[0]);
        free(stringSix[0]);
    }



    for(i=1;i<8;i++) //But here is where the problem arises. If i remove this code is runs fine.
    {
        free(stringOne[i]);
        free(stringTwo[i]);
        free(stringThree[i]);
        free(stringFour[i]);
        free(stringFive[i]);
        free(stringSix[i]);
    }


    free(listofdetails);
    free(stringOne);
    free(stringTwo);
    free(stringThree);
    free(stringFour);
    free(stringFive);
    free(stringSix);
    fclose(fp);

}
Run Code Online (Sandbox Code Playgroud)

Bil*_*nch 7

我们来看看你如何使用strtok():

for(i=1; i<8; i++) {
    stringOne[i] = malloc(sizeof(char)*6);
    stringOne[i] = strtok(NULL, " ");
}

....    

for(i=1; i<8; i++) {
    free(stringOne[i]);
}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 你非常清楚地泄漏了你分配的内存malloc().
  2. strtok() 本身不分配内存.
  3. 稍后在程序中,您尝试释放返回的指针,strtok()这将导致未定义的行为.

很明显,你不明白它是如何strtok()运作的.所以让我们试着描述它.

我们来一个字符串:"hello world and people".

char[] s = "hello world and people";
char * token = strtok(s, " ");

// The memory as s is now: "hello\0world and people\0"
// token points to "hello\0world and people"

token = strtok(NULL, " ");

// The memory at s is now: hello\0world\0and people\0"
// token points to "world\0and people"

token = strtok(NULL, " ");

// The memory at s is now: hello\0world\0and\0people\0"
// token points to "and\0people"

token = strtok(NULL, " ");

// The memory at s is now: hello\0world\0and\0people\0"
// token points to "people"

token = strtok(NULL, " ");

// The memory at s is still: hello\0world\0and\0people\0"
// token points to NULL
Run Code Online (Sandbox Code Playgroud)

请注意,我们在任何时候都没有分配任何额外的内存(除了在这种情况下在堆栈上分配的原始字符串的空间).strtok()改变原始字符串,用空字符替换分隔符.