奇怪的重新分配行为

发布于 2024-09-03 04:42:49 字数 1622 浏览 5 评论 0原文

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

#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!!!! :S

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

谢谢

注意 我完全知道以这种方式混合 C 和 C++ 是丑陋,而且我也知道如果使用这个结构会搞砸,例如:

darray_t<std::string>

这只是对 int 指针的测试。

i'm developing an array structure just for fun.
This structure, generalized by a template parameter, pre allocates a given number of items at startup, then, if "busy" items are more than available ones, a function will realloc the inner buffer .
The testing code is :

#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;
}

As you can see, i prealloc 100 integer pointers at the beginning and then i realloc them with 10 more pointers at time.
In the main function, i perform a for loop to check items integrity and, if an array item is not as i expect, i print its value and ... you know what ?
I have the following message :

!!! 11 != 135121

In fact, item at index 11, that should be '11', is 135121 !!!! :S

Can you tell me if my code is not correct?

Thanks

NOTE
I perfectly know that mixing C and C++ this way is ugly, and i know too that this structure would screw up if used, for instance :

darray_t<std::string>

This is just a test for int pointers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

长途伴 2024-09-10 04:42:49

realloc 不会自动增加内存——你必须这样做。执行例如:(

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

并且您应该处理返回 NULL 的 realloc)

realloc does not automatically grow the piece of memory - you'll have to do that. Do e.g.:

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

(and you should handle realloc returning NULL)

魄砕の薆 2024-09-10 04:42:49

块的大小不正确:

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

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

da->busy + sizeof(T) * DARRAY_REALLOC_ITEMS_STEP

The size of the block is incorrect:

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

The entire block is as big as the increment. Try

da->busy + sizeof(T) * DARRAY_REALLOC_ITEMS_STEP
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文