首页 > 解决方案 > 在函数中创建的指针不正确

问题描述

我正在尝试在 C 中实现一个整数向量。在其中创建的向量指针vector_copy大约为 0x3 或 0x2,这会导致分段错误。为什么会这样?这真的让我感到困惑,因为我有一个类似的实现vector_new

typedef struct vector {
    int* items;
    size_t size;
    size_t max;
} vector;
vector* vector_copy(vector* v) {
    vector* v2;

    memcpy(v2->items,v->items,v->max * sizeof(int*));
    if (v2->items == NULL) {
        return NULL;
    }
    v2->size = v->size;
    v2->max = v->max;
    return v2;
}
vector* vector_new(size_t initial_capacity) {
    vector* newv;
    newv->items = malloc(initial_capacity * sizeof(int*));
    if (newv->items == NULL) {
        return NULL;
    }
    newv->size = 0;
    newv->max = initial_capacity;
    return newv;
}
int main() {
    vector* v;
    vector* v2;

    v = vector_new(4);
    //new vector with capacity 4 and size 0

    vector_push(v, 1);
    vector_push(v, 2);
    //1 and 2 are pushed back

    v2=vector_copy(v);
    //vector is supposed to be copied

    vector_free(v);
    vector_free(v2);
    return 0;
}

标签: csegmentation-fault

解决方案


vector* v2;
memcpy(v2->items,v->items,v->max * sizeof(int*));

不是一个好主意。您基本上已经创建了一个指向v2某个任意位置的指针(因为您尚未对其进行初始化),该指针值可能是之前某个操作(a)v2留在堆栈上的任何值。然后,通过将字节复制到该任意位置,可能会发生各种奇怪的事情。

您实际上需要为这个新向量分配一些内存,例如:

vector *v2 = vector_new(v->max);
memcpy(v2->items, v->items, v->max * sizeof(int));

您(希望)还会注意到我已将 更改sizeof为 useint而不是int*. 我怀疑这items指向了前者的数组,在这种情况下这是正确的值。


所以下面的函数是一个更好的起点:

vector *vector_copy(vector* v) {
    // Use vector_new to get empty one with exact same properties.

    vector *v2 = vector_new(v->max);
    if (v2 == NULL) return NULL;

    // Copy data in to it and return.

    memcpy(v2->items, v->items, v->max * sizeof(int));
    v2->size = v->size;

    return v2;
}

您的函数中也有完全相同的问题(没有结构分配和错误sizeofnew,可以通过以下方式解决:

vector *vector_new(size_t initial_capacity) {
    // Allocate a vector structure, fail if no go.

    vector *newv = malloc(sizeof(vector));
    if (newv == NULL) return NULL;

    // Allocate the data area, free structure and fail if no go.

    newv->items = malloc(initial_capacity * sizeof(int));
    if (newv->items == NULL) {
        free(newv);
        return NULL;
    }

    // Set up everything needed and return it.

    newv->size = 0;
    newv->max = initial_capacity;

    return newv;
}

该功能基于 设置最大值这一事实使initial_capacity您无需设置max.vector_copy()


(a)我说“可能”是因为许多实现在重用堆栈帧内存区域方面的工作方式。但是,这绝不是保证,只有一种可能性。你应该假设它会有一些随机值,因此会表现得恰当(或不恰当,取决于你的观点)。


推荐阅读