代码之家  ›  专栏  ›  技术社区  ›  Simone Margaritelli

奇怪的真实行为

  •  2
  • Simone Margaritelli  · 技术社区  · 14 年前

    我正在开发一个数组结构只是为了好玩。 这个由模板参数概括的结构在启动时预先分配给定数量的项目,然后,如果“忙”项目多于可用项目,函数将重新分配内部缓冲区。 测试代码为:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    template <typename T> struct darray_t {
        size_t items;
        size_t busy;
        T     *data;
    };
    
    #define DARRAY_REALLOC_ITEMS_STEP 10
    
    #define da_size(da) (da)->busy
    
    template <typename T>
    void da_init( darray_t<T> *da, size_t prealloc ){
        da->items = prealloc;
        da->busy  = 0;
        da->data  = (T *)malloc( sizeof(T) * prealloc );
    }
    
    template <typename T> T *da_next( darray_t<T> *da ){
        if( da->busy >= da->items ){
            da->data   = (T *)realloc( da->data, sizeof(T) * DARRAY_REALLOC_ITEMS_STEP );
            da->items += DARRAY_REALLOC_ITEMS_STEP;
        }
        return &da->data[ da->busy++ ];
    }
    
    int main(){
        darray_t<int> vi;
        int *n;
    
        da_init( &vi, 100 );
    
        for( int i = 0; i < 101; ++i ){
            n = da_next(&vi);
            *n = i;
        }
    
        for( int i = 0; i < da_size(&vi); ++i ){
            if( vi.data[i] != i ){
                printf( "!!! %d != %d\n", i, vi.data[i] );
            }
        }
    
        return 0;
    }
    

    如您所见,我在开始预分配100个整数指针,然后用10个指针重新分配它们。 在主函数中,我执行for循环以检查项的完整性,如果数组项不是我期望的那样,我将打印它的值并…你知道吗? 我有以下信息:

    !!!!11!= 135121

    事实上,索引11中的项目应该是“11”,它是135121!!!!!

    你能告诉我我的代码是否不正确吗?

    谢谢

    注释 我完全知道混合C和C++是这样的 丑陋的 我也知道,如果使用这种结构,它会崩溃,例如:

    darray_t<std::string>
    

    这只是对int指针的测试。

    2 回复  |  直到 14 年前
        1
  •  3
  •   nos    14 年前

    realloc不会自动增长内存——你必须这样做。例如:

    da->data=(T*)realloc(da->data, sizeof(T)*(da->items+DARRAY_REALLOC_ITEMS_STEP));
    

    (您应该处理realloc返回空值)

        2
  •  1
  •   Potatoswatter    14 年前

    块的大小不正确:

    da->data   = (T *)realloc( da->data, sizeof(T) * DARRAY_REALLOC_ITEMS_STEP );
    

    整个块和增量一样大。尝试

    da->busy + sizeof(T) * DARRAY_REALLOC_ITEMS_STEP