【问题标题】:Malloc Undefined Behavior - Losing dataMalloc 未定义行为 - 丢失数据
【发布时间】:2018-07-24 00:59:02
【问题描述】:

所以,我正在使用一些内存绑定的应用程序,我有:

1 - 模拟垂直数据库上的表的两个结构数组。其中一个仅带有键(1.5M 32 位整数键),另一个带有整数键和双有效负载(150k 元组)。然后动态分配两个

2 - 2^15 个 64 位无符号整数数组

3 - 2^10 个 32 位无符号整数数组

我需要动态分配一个 32 位整数数组,我会在运行时知道它的大小。

问题是:我已经能够使用 malloc 分配这个数组,但是当我将值初始化为零时,它只是订阅了 150k 元组表的值。这意味着,我正在丢失数据。数据库研究人员可能遇到的最糟糕的事情。

“表”的分配

tamCustomer = countLines("customer.tbl");
c_customer = malloc(tamCustomer*sizeof(column_customer));
readCustomerColumn("customer.tbl", c_customer);

tamOrders = countLines("orders.tbl");
c_orders = malloc(tamOrders*sizeof(column_orders));
readOrdersColumn("orders.tbl", c_orders, sel);

分配有问题的数组

cht->tamHT = actualPopCounter;
cht->HT = malloc(sizeof(uint32_t)*cht->tamHT); 
if (cht->HT == NULL) 
       printf("deu merda\n");
for (int i=0; i<cht->tamHT; i++) 
       cht->HT[i] = 0; 

因此,在这一点之后,表 c_customer 的一半丢失了,被零订阅。

我能做些什么来避免这种情况?

编辑:结构定义:

/******** VETOR DE STRUCTS COLUMN CUSTOMER *********/
typedef struct customer_c
{
    unsigned int C_CUSTKEY;
    float C_ACCTBAL;
} column_customer;

column_customer *c_customer;

/******** VETOR DE STRUCTS COLUMN ORDERS ***********/
typedef struct orders_c
{
    unsigned int O_CUSTKEY;
} column_orders;

column_orders *c_orders;

CHT 定义:

typedef struct CHT
{
    uint64_t bitmap[CHT_BMP_SIZE];
    bucket OHT[CHT_OHT_SIZE];
    bucket *HT;
    uint32_t tamHT;
} CHT;

s pretty much the function where it occurs. This is not a small application and I一直专注于这个问题,以至于我现在无法正确思考(抱歉)。

inline void generateCHT(column_customer *c_customer, int tamCustomer, CHT * cht)
{
    uint32_t ohtOcc=0;
    uint32_t chtOcc=0;
    uint32_t ohtOccBMP=0;
    uint32_t chtOccBMP=0;

    uint64_t actualPopCounter;
    uint64_t oldPopCounter;

    //Allocate CHT
    cht->tamHT = 0;

    //Initialize OHT and bitmap
    for (int i=0; i<CHT_OHT_SIZE;i++)
    {
        cht->OHT[i]=0;
        cht->bitmap[i]=0;
    }

    for (int i=0; i<tamCustomer; i++)
    {
        switch (chtInsertBitmap(c_customer[i].C_CUSTKEY, tamCustomer, cht))
        {
            case 0:
                printf("ERROR: Something went wrong while inserting the key %u on the CHT\n", c_customer[i].C_CUSTKEY);
                break;
            case 1:
                chtOccBMP++;
                break;
            case 2:
                ohtOccBMP++;
                break;
        }
    }

    //count Population
    actualPopCounter = 0;
    for (int i=0; i<CHT_BMP_SIZE;i++)
    {
        oldPopCounter = popCount(cht->bitmap[i]>>32);
        cht->bitmap[i] = cht->bitmap[i] | actualPopCounter;
        actualPopCounter = actualPopCounter + oldPopCounter;
    }

    cht->tamHT = actualPopCounter;

    cht->HT = malloc(sizeof(uint32_t)*cht->tamHT);
    if (cht->HT == NULL)
        printf("deu merda\n");

    for (int i=0; i<cht->tamHT; i++)
        cht->HT[i] = 0;

    for (int i=0; i<tamCustomer; i++)
    {
        if (chtInsertConciseTable(c_customer[i].C_CUSTKEY, cht, tamCustomer) == 0)
            ohtOcc++;
        else
            chtOcc++;
    }
    printf("OHT has %d occupied buckets and %d on the bitmap \n", ohtOcc, ohtOccBMP);
    printf("CHT has %d occupied buckets and %d on the bitmap \n", chtOcc, chtOccBMP);
}

【问题讨论】:

  • 没有足够的代码来告诉你哪里出错了。在minimal reproducible example 上工作。您将超出数组的范围,但基于这些 sn-ps 很难判断在哪里或为什么。
  • 这确实可能是由不同的问题引起的,但没有足够的信息来了解它。
  • 首先,向我们展示用于cht 的结构。而且,除了“彩色”错误消息之外,您可能还想退出,而不是继续并填充不存在的数组:-)
  • 无论如何,您都可以将malloc/for 组合替换为cht-&gt;HT = calloc(cht-&gt;tamHT, sizeof(uint32_t));
  • 如果您使用的是 Visual Studio,请在 &amp;c_customer[0] 处放置一个写入断点,运行该程序,当您执行有问题的写入时它会停止。其他 IDE 也可能允许写断点,我会让专家们提出建议。

标签: c arrays malloc dynamic-allocation


【解决方案1】:

您可能会离开您分配的 cht-&gt;HT 数组的末尾。

bucket *HT;

...
...

cht->HT = malloc(sizeof(uint32_t)*cht->tamHT);

改用sizeof(bucket)

【讨论】:

  • .. 或 cht-&gt;HT = malloc(sizeof *(cht-&gt;HT) * cht-&gt;tamHT); 并且不必对类型进行编码
猜你喜欢
  • 2019-11-21
  • 2023-04-08
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多