结构中的数组的malloc

时间:2017-12-11 12:52:38

标签: c arrays struct malloc

我有以下代码声明一个结构:

typedef struct variable_array{
    int length;
    BUCKET * array;
}VARIABLE_ARRAY;

typedef struct bucket{
    int Hash;
    int KeyValue;
    char Data[MAX_INPUT];
    char Key[MAX_INPUT];
}BUCKET;

然后我用以下代码声明数组:

VARIABLE_ARRAY varArray[Width];

然后使用VARIABLE_ARRAY创建数组我正在使用它:

varArray[hash].array = malloc(varArray[hash].length  * sizeof(BUCKET));

但是,malloc由于某种原因从未在数组中创建多个元素。即使长度发生变化。我不确定采取什么措施来解决这个问题。

1 个答案:

答案 0 :(得分:1)

传递给malloc的内容肯定有问题,并且无法指出和/或修复某些内容,除非您没有向我们展示完整的代码。

malloc除非你做一些有趣的事情,否则不会做任何有趣的事情。 是时候看看你设定的价值观了: WidthhashvarArray[hash].length

#include<stdio.h>
#include<stdlib.h>

#define WIDTH       5
#define MAX_INPUT   32

typedef struct bucket {
    int Hash;
    int KeyValue;
    char Data[MAX_INPUT];
    char Key[MAX_INPUT];
} BUCKET;

typedef struct variable_array {
    int length;
    BUCKET * array;
} VARIABLE_ARRAY;

VARIABLE_ARRAY varArray[WIDTH];

int main(void) 
{
    int i = 0, hash = 5;

    for(i = 0; i < hash ; i++)
    {
        varArray[i].array = malloc(sizeof(BUCKET));
        if(varArray[i].array == NULL)
        {
            printf("\nWhoa! Out of memory, returning!");
            return -1;
        }
        varArray[i].array->Hash = i + 10;
        varArray[i].array->KeyValue = i + 15;
        sprintf(varArray[i].array->Data, "Data Instance: %1d", i);
        sprintf(varArray[i].array->Key, "Key Instance: %1d", i);
    }

    for(i = 0; i < hash ; i++)
    {
        printf("\nHash = %d, KeyValue = %d, %s, %s", varArray[i].array->Hash, varArray[i].array->KeyValue, varArray[i].array->Data, varArray[i].array->Key);
    }

    for(i = 0; i < hash ; i++)
    {
        free(varArray[i].array);
        varArray[i].array = NULL;
    }

    return 0;
}

它产生的输出是:

Hash = 10, KeyValue = 15, Data Instance: 0, Key Instance: 0
Hash = 11, KeyValue = 16, Data Instance: 1, Key Instance: 1
Hash = 12, KeyValue = 17, Data Instance: 2, Key Instance: 2
Hash = 13, KeyValue = 18, Data Instance: 3, Key Instance: 3
Hash = 14, KeyValue = 19, Data Instance: 4, Key Instance: 4

看起来像预期的那样。

正如您所看到的,varArray[hash].length是我根本没用过的,所以,要么我不了解您的设计,要么不需要它。我会让你决定。

可能导致问题的原因:

您坚持varArray[hash].length设置为2,因此malloc应该已经从堆中分配了一个块,其大小等于sizeof(BUCKET)的两倍。 它只是你有一个指针来访问两个相似数据类型的连续(逻辑!)块。

所以,如果我将我的代码添加到下面的代码中(这是非常丑陋的,为了便于阅读,应该避免使用BTW)

printf("\n_______");
printf("\nTake 2!\n");

varArray[0].length = 2;
varArray[0].array = malloc(varArray[0].length * sizeof(BUCKET));
if(varArray[0].array == NULL)
{
    printf("\nWhoa! Out of memory, returning!");
    return -1;
}
varArray[0].array->Hash = 10;
varArray[0].array->KeyValue = 15;
sprintf(varArray[0].array->Data, "Data Instance: %1d", 0);
sprintf(varArray[0].array->Key, "Key Instance: %1d", 0);

printf("\nHash = %d, KeyValue = %d, %s, %s", varArray[0].array->Hash, varArray[0].array->KeyValue, varArray[0].array->Data, varArray[0].array->Key);

(varArray[0].array+sizeof(BUCKET)+sizeof(varArray[0].array->Hash))->Hash = 11;
(varArray[0].array+sizeof(BUCKET)+sizeof(varArray[0].array->KeyValue))->KeyValue = 16;
sprintf((varArray[0].array+sizeof(BUCKET)+sizeof(varArray[0].array->Data))->Data, "Data Instance: %1d", 1);
sprintf((varArray[0].array+sizeof(BUCKET)+sizeof(varArray[0].array->Key))->Key, "Key Instance: %1d", 1);

printf("\nHash = %d, KeyValue = %d, %s, %s", (varArray[0].array+sizeof(BUCKET)+sizeof(varArray[0].array->Hash))->Hash, (varArray[0].array+sizeof(BUCKET)+sizeof(varArray[0].array->KeyValue))->KeyValue, (varArray[0].array+sizeof(BUCKET)+sizeof(varArray[0].array->Data))->Data, (varArray[0].array+sizeof(BUCKET)+sizeof(varArray[0].array->Key))->Key);

free(varArray[0].array);
varArray[0].array = NULL;

它会生成一个输出:

Hash = 10, KeyValue = 15, Data Instance: 0, Key Instance: 0
Hash = 11, KeyValue = 16, Data Instance: 1, Key Instance: 1
Hash = 12, KeyValue = 17, Data Instance: 2, Key Instance: 2
Hash = 13, KeyValue = 18, Data Instance: 3, Key Instance: 3
Hash = 14, KeyValue = 19, Data Instance: 4, Key Instance: 4
_______
Take 2!

Hash = 10, KeyValue = 15, Data Instance: 0, Key Instance: 0
Hash = 11, KeyValue = 16, Data Instance: 1, Key Instance: 1

再次,完全符合预期。

显然在这里工作的是:

// For this code, accessing it like below, will result in a Segmentation Fault!!!
varArray[1].array->Hash = 11;

因为,在上面的代码段中,我没有将varArray[1].array初始化为指向BUCKET类型的变量的地址实例。 因此,如果您已经将varArray[hash].length * sizeof(BUCKET)传递给malloc的非预期错误/错误,请确保在malloc没有返回{NULL时分配了大量内存1}}。

我认为这是您在尝试访问下一个索引时获得分段错误的确切原因,方法是在某处增加hash

您的陈述:

  

但是,malloc由于某种原因从未在数组中创建多个元素。即使长度改变了。

我的猜测是,通过分段错误,您假设在分配内存时未分配内存。只是你没有以正确的方式访问它。