c - 指针和 realloc 的问题,C 中的程序崩溃错误

标签 c arrays pointers memory-management

main.c

#include <stdio.h>
#include "poly.h"

int main (void)
{
  struct poly *p0 = polySetCoefficient (polySetCoefficient (polySetCoefficient (polyCreate() , 0, 4.0), 1, -1.0), 10, 2.0);

  //polyPrint (p0);

  return 0;
}

poly.c 中,我刚刚包含了我正在处理的两个函数,似乎 polySetCoefficient 是给我带来问题的函数。我已经注释掉了 printf 语句,但我使用它们来确定程序崩溃的确切位置。显然,它实际上在崩溃之前经历了整个函数,所以我不确定错误来自哪里。其次,在我的 main.c 文件中,我只调用了两个函数。另一个问题是,每次我通过 polySetCoefficient 时,我以前的条目都会被替换为 0。我认为这可能是因为我将数组中的元素设置为 0 的方式,但我仔细确保将元素设置为 0,从数组的先前大小到数组的新大小,不包括最后一个索引。

struct poly *polyCreate()
{

    struct poly *q;

    q = malloc(sizeof(struct poly));
    q->c = malloc(sizeof(double));

        q->c[0] = 0.0;

    q->size = 0;

    //printf("polyCreate: %g\n", q->c[0]);

    return q;
}

struct poly *polySetCoefficient(struct poly *p, int i, double value)
{
    //printf("%d\n", i*sizeof(double));

    if (p->size < i)
    {
        printf("Old: %d, New: %d\n", sizeof(p->c)/sizeof(double), i);

        p->c = realloc(p->c, i+1*sizeof(double));

        printf("New: %d \n", sizeof(p->c));

        for(int l = p->size; l <= i; l++ )
        {

            if(l != i)
            {
                p->c[l] = 0;
                printf("set to 0\n");
            }
            else
            {
                p->c[l] = value;
                printf("F:set to %g\n", p->c[i]);
            }
        }

        printf("Did we come here?\n");

        p->size = i;

    } else {

        p->c[i] = value;

    }

    printf("The %d'th coefficient is %g\n", i, p->c[i]);

    printf("Cof 0: %g, Cof 1: %g, Cof 10: %g", p->c[0], p->c[1], p->c[10]);


    return p;


}

poly.h

struct poly
{
    double *c;
    int size, length;
};


struct poly *polyCreate();
struct poly *polyDelete(struct poly *p);
struct poly *polySetCoefficient (struct poly *p, int i, double value);
double polyGetCoefficient (struct poly *p, int i);
int polyDegree (struct poly *p);
void polyPrint (struct poly *p);
struct poly *polyCopy (struct poly *p);
struct poly *polyAdd (struct poly *p0, struct poly *p1);
struct poly *polyMultiply (struct poly *p0, struct poly *p1);
struct poly *polyPrime (struct poly *p);
double polyEval (struct poly *p, double x);

最佳答案

此版本的代码可以干净地编译并合理地(但不是真正正确地)运行而不会崩溃。

一个关键的变化是由 immibis 标识的那个在他的 answer ,修正后的尺寸计算。

另一个关键变化是当还没有系数 10 时不打印系数 10。如果您尝试更早地打印它,那么您将调用未定义的行为;任何事情都可能发生。

我修复了一些 printf() 格式;在 64 位机器上,您需要使用 %zu(或必要时使用 %zd)来打印 size_t。我删除了结构中未使用的 length 成员。我真的不知道如何整齐地格式化你的单行多调用语句。我不介意超过 80 个字符行,但我通常不会达到 120 个字符行。我绝对更喜欢 p1 版本,尤其是因为它可以像你一样进行错误检查去。目前,我在应该进行分配错误检查的地方使用了 assert(ptr != 0);

输出:

The 0'th coefficient is 4
The 1'th coefficient is -1
Old: 1, New: 10
New: 8
p[1] set to 0
p[2] set to 0
p[3] set to 0
p[4] set to 0
p[5] set to 0
p[6] set to 0
p[7] set to 0
p[8] set to 0
p[9] set to 0
p[10] set to 2
Did we come here?
The 10'th coefficient is 2
Cof 0: 4, Cof 1: 0, Cof 10: 2

请注意,当您扩展到 10 时,您已经用零破坏了第一个系数。

代码:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

struct poly
{
    double *c;
    int size;
};

struct poly *polyCreate(void);
struct poly *polySetCoefficient(struct poly *p, int i, double value);

int main(void)
{
    /* I don't know how to format this neatly! */
    struct poly *p0 = polySetCoefficient(
        polySetCoefficient(
            polySetCoefficient(polyCreate(), 0, 4.0),
            1, -1.0),
        10, 2.0);

    assert(p0 != 0);

    /*
    struct poly *p1 = polyCreate();
    p1 = polySetCoefficient(p1, 0,  4.0),
    p1 = polySetCoefficient(p1, 1, -1.0);
    p1 = polySetCoefficient(p1, 10, 2.0);
    */

    return 0;
}

struct poly *polyCreate(void)
{
    struct poly *q = malloc(sizeof(struct poly));
    assert(q != 0);
    q->c = malloc(sizeof(double));
    assert(q->c != 0);

    q->c[0] = 0.0;
    q->size = 1;

    return q;
}

struct poly *polySetCoefficient(struct poly *p, int i, double value)
{
    assert(p != 0);

    if (p->size < i)
    {
        printf("Old: %zu, New: %d\n", sizeof(p->c)/sizeof(double), i);

        p->c = realloc(p->c, (i+1)*sizeof(double));
        assert(p->c != 0);

        printf("New: %zu\n", sizeof(p->c));

        for (int l = p->size; l <= i; l++)
        {
            if (l != i)
            {
                p->c[l] = 0;
                printf("p[%d] set to 0\n", l);
            }
            else
            {
                p->c[l] = value;
                printf("p[%d] set to %g\n", i, p->c[i]);
            }
        }

        printf("Did we come here?\n");

        p->size = i;
    }
    else
    {
        p->c[i] = value;
    }

    printf("The %d'th coefficient is %g\n", i, p->c[i]);

    if (i >= 10)
        printf("Cof 0: %g, Cof 1: %g, Cof 10: %g", p->c[0], p->c[1], p->c[10]);

    return p;
}

关于c - 指针和 realloc 的问题,C 中的程序崩溃错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20137037/

相关文章:

c++ - 我可以获得指针所属的unique_ptr(如果有的话)吗?

C++ 矩阵到动态二维数组

c - 即使没有分配足够的内存,strcat() 和 strcpy() 也能工作

c - 实现重定向。 Unix 外壳。

当只有一些为空时,Javascript变量列表obj.names为空

python - 从Python文件中读取数组

arrays - 如何找到相同数量和颜色的组在 MATLAB 中给出不同的颜色?

ios - 对象属性的 Getter 需要返回 UnsafeMutablePointer<T>?

c - 练习 : Using pointers cross-function in C Language returns error "invalid type argument of unary ‘*’ (have ‘int’ )"

c - 如何在 c 中转换一个指向 int 的指针(以获取它的 ascii 值)