尝试从堆中释放字节时程序崩溃

发布于 2025-01-14 21:27:24 字数 2216 浏览 4 评论 0原文

在我的程序中,我试图获取一个完整的堆,将其发送到另一个函数,创建一个更大大小的新堆,复制旧堆中的值,释放旧堆并返回新堆以继续使用。然而,当我尝试释放堆时,我遇到了总线错误。据我了解,我将释放这个旧堆,并且新堆应该继续并在此实现中取代旧堆,直到它也需要更新。我尝试更改正在释放的堆,但这没有什么区别。此外,我尝试不使用“grades = arr”行,因为它只复制 arr 的地址,不会做太多事情,但它确实允许我的程序在崩溃之前运行更长时间,所以我选择保留它。任何对此的帮助将不胜感激。对于上下文,grades 是原始堆,最初分配了 40 字节的内存。

void gradeScanner(int gradeCount, int allocCount, double* grades)
{
    int i = 0;
    while (i != 5) {
        scanf("%lf", &myGrade);
        if (myGrade > 0 && i == 4) {
            *(grades + gradeCount) = myGrade;
            gradeCount++;
            allocCount++;
            printf("%s", "stored ");
            printf("%lf", myGrade);
            printf("%s", "in the heap at ");
            printf("%p\n", (void*)(grades + i));
            printf("%s", "heap at ");
            printf("%p", (void*)(grades + i));
            printf("%s\n", "is full");
            expander(grades, gradeCount, allocCount);
            i = 0;
        }
        else if (myGrade > 0) {
            *(grades + gradeCount) = myGrade;
            gradeCount++;
            printf("%s", "stored ");
            printf("%lf", myGrade);
            printf("%s", "in the heap at ");
            printf("%p\n", (void*)(grades + i));
            i++;
        }
        else if (myGrade < 0) {
            i = 5;
            average(grades, gradeCount);
            evaluator(grades, gradeCount);
        }
    }
}

double* expander(double* grades, int gradeCount, int allocCount)
{
    int x = allocCount * 40;
    double* arr = (double*)malloc(x);
    printf("%s", "Allocated ");
    printf("%d", x);
    printf("%s", " bytes to the heap at ");
    printf("%p\n", (void*)arr);
    printf("%s", "copied ");
    for (int i = 0; i < gradeCount; i++) {
        printf("%s", "hiya");
        *(arr + i) = *(grades + i);
    } //for
    oldAlloc = x;
    grades = arr;
    free(grades);
    printf("%d", gradeCount);
    printf("%s", " grades from ");
    printf("%p", (void*)grades);
    printf("%s", " to ");
    printf("%p\n", (void*)arr);
    printf("%s", " Freed ");
    printf("%d", oldAlloc);
    printf("%s", " byes from the heap at ");
    printf("%p\n", (void*)grades);
    return arr;
} //expander

In my program here, I am trying to take a full heap, send it to another function, create a new heap of larger size, copy over values from old heap, free the old heap and return the new heap to continue to be used. However when I try to free the heap I run into a bus error. To my understanding, I am to free this old heap, and the new heap should continue and take the place of the old heap in this implementation, until it too needs to be renewed. I tried to change the heap being freed, but that made no difference. Additionally, I tried to do without the "grades = arr " line as that only copies the address of arr and wouldn't do much, but it does allow my program to run a bit longer before crashing so I opted to leave it in. Any help with this would be appreciated. for context, grades is the original heap and is originally allocated 40 bytes of memory.

void gradeScanner(int gradeCount, int allocCount, double* grades)
{
    int i = 0;
    while (i != 5) {
        scanf("%lf", &myGrade);
        if (myGrade > 0 && i == 4) {
            *(grades + gradeCount) = myGrade;
            gradeCount++;
            allocCount++;
            printf("%s", "stored ");
            printf("%lf", myGrade);
            printf("%s", "in the heap at ");
            printf("%p\n", (void*)(grades + i));
            printf("%s", "heap at ");
            printf("%p", (void*)(grades + i));
            printf("%s\n", "is full");
            expander(grades, gradeCount, allocCount);
            i = 0;
        }
        else if (myGrade > 0) {
            *(grades + gradeCount) = myGrade;
            gradeCount++;
            printf("%s", "stored ");
            printf("%lf", myGrade);
            printf("%s", "in the heap at ");
            printf("%p\n", (void*)(grades + i));
            i++;
        }
        else if (myGrade < 0) {
            i = 5;
            average(grades, gradeCount);
            evaluator(grades, gradeCount);
        }
    }
}

double* expander(double* grades, int gradeCount, int allocCount)
{
    int x = allocCount * 40;
    double* arr = (double*)malloc(x);
    printf("%s", "Allocated ");
    printf("%d", x);
    printf("%s", " bytes to the heap at ");
    printf("%p\n", (void*)arr);
    printf("%s", "copied ");
    for (int i = 0; i < gradeCount; i++) {
        printf("%s", "hiya");
        *(arr + i) = *(grades + i);
    } //for
    oldAlloc = x;
    grades = arr;
    free(grades);
    printf("%d", gradeCount);
    printf("%s", " grades from ");
    printf("%p", (void*)grades);
    printf("%s", " to ");
    printf("%p\n", (void*)arr);
    printf("%s", " Freed ");
    printf("%d", oldAlloc);
    printf("%s", " byes from the heap at ");
    printf("%p\n", (void*)grades);
    return arr;
} //expander

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月苍老的讽刺 2025-01-21 21:27:24
grades = arr;  
free(grades);

出故障了。程序通过将 grades 指向新数组来泄漏旧的 grades 数组,然后释放新数组。

free(grades);
grades = arr;  

将释放旧的grades数组,然后将grades指向新数组。

注:以下内容纯属猜测。

我怀疑 gradeScanner 应该看起来更像这样:

void gradeScanner(int gradeCount, int allocCount, double* grades)
{
    while (true) // keep going until user inputs bad grade 
    {
        if (scanf("%lf", &myGrade) == 1) // got a valid input from user
        {
            if (myGrade >= 0) // got a valid grade
            {
                if (gradeCount == allocCount) // array full. expand it
                {
                    allocCount++; // strongly consider expanding by more than one 
                                  // memory allocation and all the copying is expensive.
                                  // Unless you have memory constraints, it's better 
                                  // to waste a bit of memory in order to do fewer
                                  // reallocations and copies.
                    expander(grades, gradeCount, allocCount);
                }
                *(grades + gradeCount) = myGrade; // store the grade
                gradeCount++;
            }
            else // didn't get a valid grade
            {
                average(grades, gradeCount);
                evaluator(grades, gradeCount);
                return; // done scanning grades
            }
        }
        else // user didn't input a number
        {
            // clean up bad input and request a new one
        }
    }
}
grades = arr;  
free(grades);

is out of order. The program leaks the old grades array by pointing grades at the new array and then releases the new array.

free(grades);
grades = arr;  

will release the old grades array and then point grades at the new array.

Note: What follows is guesswork.

I suspect gradeScanner should look more like this:

void gradeScanner(int gradeCount, int allocCount, double* grades)
{
    while (true) // keep going until user inputs bad grade 
    {
        if (scanf("%lf", &myGrade) == 1) // got a valid input from user
        {
            if (myGrade >= 0) // got a valid grade
            {
                if (gradeCount == allocCount) // array full. expand it
                {
                    allocCount++; // strongly consider expanding by more than one 
                                  // memory allocation and all the copying is expensive.
                                  // Unless you have memory constraints, it's better 
                                  // to waste a bit of memory in order to do fewer
                                  // reallocations and copies.
                    expander(grades, gradeCount, allocCount);
                }
                *(grades + gradeCount) = myGrade; // store the grade
                gradeCount++;
            }
            else // didn't get a valid grade
            {
                average(grades, gradeCount);
                evaluator(grades, gradeCount);
                return; // done scanning grades
            }
        }
        else // user didn't input a number
        {
            // clean up bad input and request a new one
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文