为什么我的指针算术在这个数组中失败

时间:2014-11-21 04:12:46

标签: c arrays pointers

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

// Resource
typedef struct _Resource Resource;

// ResourceBuffer
typedef struct _ResourceBuffer ResourceBuffer;
ResourceBuffer *resource_buffer_new(int);
ResourceBuffer *resourceBuffer;
void resource_buffer_test();

struct _ResourceBuffer {
    char *id;
    int size;
    Resource **buffer;
};

struct _Resource {
    int id;
    char *status;
};

Resource *resource_new(int i) {
    Resource *r = malloc(sizeof(*r));
    r->status = "groovy";
    r->id = i;
    return r;
}

void resource_buffer_test() {

    printf("buftest has buf as %d\n",resourceBuffer->buffer);
    printf("buftest has drefbuf as %d\n",*(resourceBuffer->buffer));

    Resource *bp[resourceBuffer->size];
    bp[0] = *(resourceBuffer->buffer+0);
    bp[1] = *(resourceBuffer->buffer+1); 
    bp[2] = *(resourceBuffer->buffer+2);
    int i = 0;
    for (i = 0; i < 3; i++) {
        printf("address is %d\n", bp[i]);
    }
    for (i = 0; i < 3; i++) {
        //printf("ptrBuffer r%d is %s\n", i, (*((Resource **)(resourceBuffer->buffer)+i))->status);
        printf("Buffer r%d is %s\n", bp[i]->id, bp[i]->status);
    }
}

ResourceBuffer *resource_buffer_new(int bufferSize) {
    ResourceBuffer *r = malloc(sizeof(*r));
    Resource *b[bufferSize];
    int i;
    for (i = 0; i < bufferSize; i++) {
        b[i] = resource_new(i);
    }
    for (i = 0; i < bufferSize; i++) {
        printf("res address is %d\n", b[i]);
        printf("pnt address is %d\n", &b[i]);
    }
    printf("b address is %d\n", b);
    r->buffer = b;
    printf("buffer set to %d\n", r->buffer);
    r->size = bufferSize;
    r->id = "foo";
    return r;
}

int main(int argc, char** argv) {
    // initialize buffer
    resourceBuffer = resource_buffer_new(3);
    resource_buffer_test();

    return (EXIT_SUCCESS);
}

输出结果为:

res address is 36585520
pnt address is 783569984
res address is 36585552
pnt address is 783569992
res address is 36585584
pnt address is 783570000
b address is 783569984
buffer set to 783569984
buftest has buf as 783569984
buftest has drefbuf as 36585520
address is 36585520
address is 36585552
address is 36585520
Buffer r0 is groovy
Buffer r1 is groovy
Buffer r0 is groovy

让我感到困惑的是最后6行......为什么resource_buffer_test() b[0]b[2]最终指向资源结构r0?

由于某种原因,这部分失败了:

bp[0] = *(resourceBuffer->buffer+0);
bp[1] = *(resourceBuffer->buffer+1); 
bp[2] = *(resourceBuffer->buffer+2);

*(resourceBuffer->buffer+2)以某种方式最终指向数组中的第一个元素,而不是第三个元素。

为什么会这样?是什么原因导致C指针算术将*(resourceBuffer->buffer+2)重置回*(resourceBuffer->buffer+0)

真正奇怪的是(对我而言)......当我将resource_buffer_new函数更改为这样时:

ResourceBuffer *resource_buffer_new(int bufferSize) {
    ResourceBuffer *r = malloc(sizeof(*r));
    Resource *b[bufferSize+1];

(注意*b[bufferSize+1]) - 然后按预期工作..

为什么我的缓冲区数组需要额外的空间才能使指针算法工作?

1 个答案:

答案 0 :(得分:0)

r->buffer = b;是你的问题。从b返回后,resource_buffer_new()是一个超出范围的局部变量。如果你使b静态或分配它,那就没问题了。