有没有办法限制指针被特定函数修改?

时间:2015-06-19 02:35:26

标签: c pointers

这是基于我之前的问题:Is this an appropriate use of const qualifiers in C?

Vector.h

typedef struct _Vector Vector;
Vector* vector_init(const UInt32 size);
void*  vector_get(const Vector *v, UInt32 idx);
void   vector_add(Vector *v, void* const elem);
void   vector_set(Vector *v, const UInt32 idx, void* const elem);
...etc

在Vector.c中:

struct _Vector{
    UInt32 used;
    UInt32 size;
    void** arr;
};

Vector* vector_init(const UInt32 size){
    Vector* v = malloc(sizeof(Vector));
    v->used = 0;
    v->size = size;
    v->arr = malloc(size*sizeof(void*));
    return v;
}

void* vector_get(const Vector *v, const UInt32 idx){
    if ( idx >= v->used )
        exitAtError("Vector","Array out of bounds");
    return v->arr[idx];
}

void vector_add(Vector *v, void* const elem){
    if( v->used == v->size )
        vector_resize(v);
    v->arr[v->used++] = elem;
}
...etc

我希望阻止void** arr中的_Vector被我的实现意外修改,作为编译时的警告/错误。我无法使arr成为const void**,因为我不希望向量是永久性的,并且希望避免丢弃const。

这里的想法是usedsize是与我的函数范围直接相关的数据,而arr只是我不想要的一种元数据修改。 arr是不透明的,因此我无法直接修改它,但我可以使用memcpy来强制转换或直接覆盖。

在此示例中,似乎没有必要强制执行此访问,因为每个函数都是直接的,但此示例主要用于演示目的。

我有两个相关问题可以同时回答:

  1. 这种访问限制是否可以使用C中的语言支持,如果没有,指针的不透明性是否足以阻止直接修改数据?
  2. 我只是在这里追逐我的尾巴,而应该专注于生成记录良好且结构合理的代码,这甚至不会成为问题?
  3. 我在Is there a way to protect a class variable from being modified outside of a function

    中看到了相关问题

    该用户似乎在C#中处于类似的困境;我的问题#2与那种情况有关。

    编辑:我想从大家的意见来看,我正在通过寻找某种类型的魔法关键字来为我记录内容,从而将语言推到原始设计之外。要么将我的数据隐藏在另一个抽象之后,要么在结构上分离我的功能以防止诱惑数据,这似乎是最好的解决方案。

3 个答案:

答案 0 :(得分:1)

main

我猜这种变化会对你有用。否则,使用getter和setter函数的抽象,而不是直接分配给每个函数中的结构成员。这样,你不必担心它。

答案 1 :(得分:0)

  1. 我相信你可以做void* const之类的事情。 const位置使指针和指针指向的数据不可变。

  2. 在我看来(这并不多说),希望指针的数据不被修改似乎是一个合理的愿望,因为它有助于记录代码对传递给它的数据的作用(不是修改它。)

答案 2 :(得分:0)

由于您在C / C ++中寻找解决方案,我在C ++中创建了一个抽象层来保护class array{ public: void setArray(void** key) { arr=key; } void** getArray() { return &(*arr); } private: void** arr; }; struct Vector: public array{ int used; int size; }; Vector* vector_init(const int size){ Vector* v =(Vector*) malloc(sizeof(Vector)); v->used = 0; v->size = size; void** tem=v->getArray(); tem=(void**) malloc(size*sizeof(void*)); v->setArray(tem); return v; } ,如下所示。请检查它是否符合您的要求。

For data As Integer = 0 To InvestorGridView.Rows.Count - 1 

Response.Wri‌​te(InvestorGridView.Rows(data).Cells(0).Text)

Response.Wri‌​te(InvestorGridView.Rows(data).Cells(1).Text)

Response.Wri‌​te(InvestorGridView.Rows(data).Cells(2).Text)

Next

演示:http://coliru.stacked-crooked.com/a/005b335e5fb372ce