realloc在功能上不起作用

时间:2011-11-02 08:59:32

标签: c realloc

int *f, *l;

int main(){
    int *a;
    a = calloc(1, sizeof(int));
    f = l = a;
    put(&a, 1);
    put(&a, 3);
    put(&a, 2);
    _getch();
    return 0;
}

void put(int **a, int d){
    printf("--%d--", sizeof(*a));          //always == 4
    void *tmp = (int *)realloc(*a, sizeof(*a) + sizeof(int)); 
    if (temp)                              //allocated succesfully
        *a = temp;
    else
        printf("Allocating a failed");
    l++;
}

我尝试基于int指针创建队列模型。

我已经纠正了一些样本。但它仍然失败了。 你能帮忙吗?

7 个答案:

答案 0 :(得分:1)

a是一个int指针(int *),因此它的大小如果是4个字节(在你的机器上)你应该跟踪分配的内存的大小。

例如:

int *f, *l;

int main(){
    int *a;
    size_tasize = 0;
    a = calloc(1, sizeof(int));
    f = l = a;
    asize = sizeof(int);
    put(a, 1, &asize);
    put(a, 3, &asize);
    put(a, 2, &asize);
    _getch();
    return 0;
}

void put(int *a, int d, size_t * asize){
    printf("--%d--\n", asize);        //always == 4
    void *tmp = (int *)realloc(a, *asize + sizeof(int));
    (*asize) += 4;
    if (tmp)
        a = tmp;      //allocated succesfully
    else
        printf("Reallocating of 'a' size %d failed\n", asize);
    l++;
}

答案 1 :(得分:1)

在C中,无法知道指针引用的数组的大小:

int a[25]; // Known size
int *b = a; // Unknown size

所以sizeof()只打印32位平台上4个字节的指针大小。

如果您需要大小,请分配如下结构:

struct Mem {
    int size;
    int a[1];
}

使用sizeof(struct Mem) + sizeof(int) * amount确定要分配的内存量,将其分配给指针。现在,您可以将内存与ptr->a[x]一起使用。

请注意,它将分配更多的内存(通常是4个字节),但这种方法适用于不同的对齐方式,指针大小等。

答案 2 :(得分:1)

sizeof(a)是指针的大小,而不是a指向的大小。

答案 3 :(得分:0)

您正在修改函数中的局部变量a,而不是主函数中的变量a。你需要从put()返回一个新值,或者传入指向你的指针(int ** a)的指针来修改它。

例如:

int *put(int *a, int d);

int main(){
    int *a;
    a = calloc(1, sizeof(int));
    a = put(a, 1);
    ...
}

int *put(int *a, int d){
    void *tmp = (int *)realloc(a, sizeof(a) + sizeof(int));
    if (tmp)
        a = tmp;      //allocated succesfully
    else
        printf("Reallocating of 'a' size %d failed\n", sizeof(a));
    return a;
}
在您的情况下,

sizeof(a)将始终返回4。它返回指针的大小,而不是指针指向的内存大小。

答案 4 :(得分:0)

而不是做

if (tmp)
    a = tmp;

返回tmp并将其分配给main中的a

答案 5 :(得分:0)

如果要将一个新块重新分配给除已定义它之外的函数中的指针,则必须将指针传递给该指针或返回新分配的块并将其收集到该指针中。调用函数中的旧块,否则您将更新副本。

答案 6 :(得分:0)

整个概念并不像你想象的那样有效。

  • sizeof a内容无法按照您的意图运作。
  • 重新分配本身是错误的,因为您没有将新地址返回给调用者。
  • 您没有关于数据长度的信息。

我建议如下:

struct memblock {
    unsigned int alloced;
    unsigned int len;
    int * data;
}

// in order to prealloc
char add_realloc(struct memblock * mb, unsigned int add) {
    add += mb->alloced;
    int * tmp = realloc(mb->data, sizeof(*mb) + add * sizeof(*(mb->data)));
    if (!tmp) return 0;
    mb->data = tmp;
    mb->alloced = add;
    return 1;
}

char put(struct memblock * mb, int d) {
    if (mb->len == mb->alloced) {
        // realloc
        if (!add_realloc(mb, 1)) return 0;
    }
    mb->data[mb->len++] = d;
    return 1;
}

int main(){
    struct memblock a = {} // init with all zeros.
    // Calling realloc() with a NULL pointer is like malloc().

    // we put 3 values. Prealloc for not to have to realloc too often.
    if (add_realloc(&a, 3) {
        // now we are safe. Don't check the return values - it is guaranteed to be ok.
        put(&a, 1);
        put(&a, 3);
        put(&a, 2);
    }

    return 0;
}