Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 动态分配C结构?_C++_C_Memory_Allocation - Fatal编程技术网

C++ 动态分配C结构?

C++ 动态分配C结构?,c++,c,memory,allocation,C++,C,Memory,Allocation,我想动态分配一个C结构: typedef struct { short *offset; char *values; } swc; “偏移量”和“值”都应该是数组,但它们的大小在运行时之前是未知的 如何为我的结构和结构的数组动态分配内存?使用malloc函数或calloc动态分配内存。 然后在谷歌上搜索以获取示例 The calloc function initializes allocated memory to zero. 您将需要一个函数来执行此操作。 类似(我的C/C

我想动态分配一个C结构:

typedef struct {
    short *offset;
    char *values;
} swc;
“偏移量”和“值”都应该是数组,但它们的大小在运行时之前是未知的


如何为我的结构和结构的数组动态分配内存?

使用malloc函数或calloc动态分配内存。 然后在谷歌上搜索以获取示例

The calloc function initializes allocated memory to zero.

您将需要一个函数来执行此操作。 类似(我的C/C++生锈了)

语法可能有点错误,但这通常是您需要的。如果你使用C++,那么你可能需要一个类,构造函数采用2个ARG而不是MaSeCube,但是做的非常类似。
swc *a = (swc*)malloc(sizeof(swc));
a->offset = (short*)malloc(sizeof(short)*n);
a->values = (char*)malloc(sizeof(char)*n);

其中n=每个数组中的项数,a是新分配的数据结构的地址。在释放()之前,不要忘记释放()偏移量和值

你必须分开做。首先分配结构,然后为数组分配内存

在C中:

<>在C++中,你不应该做这样的事情。

你想分配内存,也可能使用sisiffes()来分配正确的空间量。 类似于:
structVariable=(*swc)malloc(sizeof(swc))

我们应该做到这一点

swc* a = malloc(sizeof(*a));
a->offset = calloc(n, sizeof(*(a->offset)));
a->values = calloc(n, sizeof(*(a->values)));
您不应该在c中使用void*。。。在C++中,你必须!p> 在C中:

swc *s = malloc(sizeof *s); // assuming you're creating a single instance of swc
if (s)
{
  s->offset = malloc(sizeof *(s->offset) * number_of_offset_elements);
  s->values = malloc(sizeof *(s->values) * number_of_value_elements);
}
在C++中:

try
{
  swc *s = new swc;
  s->offset = new short[number_of_offset_elements];
  s->values = new char[number_of_value_elements];
}
catch(...)
{
   ...
}

注意,在C++中,使用向量而不是动态分配的缓冲区可能更好:

struct swc 
{
  std::vector<short> offset;
  std::vector<char> values;
};

swc *a = new swc;

在这里的许多正确答案中需要补充一点:您可以
malloc
一个过大的结构来容纳最后一个成员中大小可变的数组

struct foo {
   short* offset;
   char values[0]
};
后来

struct *foo foo1 = malloc(sizeof(struct foo)+30); // takes advantage of sizeof(char)==1
数组中为30个对象留出空间。你仍然需要这样做

foo1->offsets = malloc(30*sizeof(short));
如果希望它们使用相同大小的数组

我通常不会真的这样做(如果结构需要扩展,维护噩梦),但它是工具包中的一个工具


[这里用c编写代码。您需要用c++强制转换
malloc
(或者更好地使用
new
和RAII习惯用法)]

除上述内容外,我还希望如下所示释放分配的内存

    typedef struct { 
    short *offset; 
    char *values; 
} swc;

swc* createStructure(int Count1, int Count2) { 
  swc *s1 = new swc(); 
  s1->offset = new short[Count1]; 
  s1->values = new char[Count2]; 
  return s1; 
} 

int _tmain(int argc, _TCHAR* argv[])
{
    swc *mystruct;
    mystruct = createStructure(11, 11);

    delete[] mystruct->offset;
    delete[] mystruct->values;
     delete mystruct;
    return 0;
}
在C中:

在C中++

struct swc
{
    std::vector<short>   offset;
    std::vector<char>    values;
    swc(unsigned int size)
        :offset(size)
        ,values(size)
    {}
};
struct-swc
{
std::矢量偏移;
std::向量值;
swc(无符号整数大小)
:偏移量(大小)
,值(大小)
{}
};

大多数答案都是正确的。我想补充一些你没有明确提出的问题,但可能也很重要

C/C++数组>强>不要在内存中存储自己的大小<强>。因此,除非您希望

offset
values
具有编译时定义的值(在这种情况下,最好使用固定大小的数组),否则您可能希望将这两个数组的大小存储在
结构中

typedef struct tagswc {
    short  *offset;
    char   *values;
    // EDIT: Changed int to size_t, thanks Chris Lutz!
    size_t offset_count;
    size_t values_count; // You don't need this one if values is a C string.
} swc;

免责声明:我可能错了。例如,如果所有
swc
实例的所有
offset
s具有相同的大小,则最好将
offset\u count
存储为全局成员,而不是
结构的成员。关于
值_count
也可以这样说。另外,如果
values
是一个C字符串,您不需要存储它的大小,但要注意类似的问题。

因为还没有人提到过它,有时候在一次分配中获取这段内存是很好的,所以您只需在一件事上调用free()

swc* AllocSWC(int items)
{
    int size = sizeof(swc); // for the struct itself
    size += (items * sizeof(short)); // for the array of shorts
    size += (items * sizeof(char)); // for the array of chars
    swc* p = (swc*)malloc(size);
    memset(p, 0, size);
    p->offset = (short*)((char*)swc + sizeof(swc)); // array of shorts begins immediately after the struct
    p->values = (char*)((char*)swc + sizeof(swc) + items * sizeof(short)); // array of chars begins immediately after the array of shorts
    return p;
}

当然,这更难读取和维护(特别是在首次分配阵列后动态调整阵列大小时)。这只是我在很多地方看到的一种替代方法。

**如果**您不打算调整数组的大小,那么只需调用
malloc()
就可以了

然后,只需调用
free()
即可释放它


(一般来说,考虑到对齐的考虑,但是对于一组短线,后面是字符数组),你会很好。

在Mac中不需要强制转换MalOC的结果,但是在C++中。sizeof(char)总是1。@joe:sizeof(char)可能总是1。但它仍然很好,有它的代码。它的行为类似于记录您的意图(并且在运行时不会花费任何代价!)。同时使用sizeof(*a)和sizeof(a->values[0])意味着您不会在代码中重复该类型。注意sizeof是编译时的,所以它是安全的。首先,强制转换
malloc()
的返回值是一种有问题的做法,所以不要表现得像你喜欢的辩论是“正确的”一方。它已经被辩论过很多次了,这些评论并不是重复辩论的地方。如果你需要C++兼容,你没有选择,但是如果你不选择,我建议你不要这么做,因为如果<代码> A- >偏移量< /C> >类型改变为<代码>长< /C> >,你必须改变< <代码> MalCube()> /Cube >(以及任何你的代码> RealCurror) s,你也可以调用)或者面对严重的bug,这会导致超出必要的维护。(下一条评论中不含此内容)其次,出于大致相同的原因,您应该使用
sizeof(*a)
sizeof(*a->offset)
而不是
sizeof(swc)
sizeof(short)
。如果
a
的类型改变(或者更可能的是,
a->offset
的类型从
short
变为
long
),使用变量而不是类型将允许您仅更改声明变量的行,而不是更改其上
malloc()
realloc()
的所有行。如果他们都从变量(或
struct
member)推断出正确的类型,那么如果我们必须将该类型更改为另一个类型,我们就不会那么头疼了。每个人都赢了。你是问C还是C++?最好的解决方案会因您使用的语言而异。下面是如何分配的好例子。在结构中保存数组的大小可能是一个好主意,以使其更通用。然后,您可以编写通用访问
typedef struct
{
    short *offset;
    char  *values;
} swc;

/// Pre-Condition:  None
/// Post-Condition: On failure will return NULL.
///                 On Success a valid pointer is returned where
///                 offset[0-n) and values[0-n) are legally de-refrancable.
///                 Ownership of this memory is returned to the caller who
///                 is responsible for destroying it via destroy_swc()
swc *create_swc(unsigned int size)
{
    swc *data    = (swc*)  malloc(sizeof(swc));
    if (data)
    {
        data->offset = (short*)malloc(sizeof(short)*n);
        data->values = (char*) malloc(sizeof(char) *n);
    }
    if ((data != NULL) && (size != 0) && ((data->offset == NULL) || (data->values == NULL)))
    {
        // Partially created object is dangerous and of no use.
        destroy_swc(data);
        data = NULL;
    }
    return data;
}
void destroy_swc(swc* data)
{
    free(data->offset);
    free(data->values);
    free(data);
}
struct swc
{
    std::vector<short>   offset;
    std::vector<char>    values;
    swc(unsigned int size)
        :offset(size)
        ,values(size)
    {}
};
typedef struct tagswc {
    short  *offset;
    char   *values;
    // EDIT: Changed int to size_t, thanks Chris Lutz!
    size_t offset_count;
    size_t values_count; // You don't need this one if values is a C string.
} swc;
swc* AllocSWC(int items)
{
    int size = sizeof(swc); // for the struct itself
    size += (items * sizeof(short)); // for the array of shorts
    size += (items * sizeof(char)); // for the array of chars
    swc* p = (swc*)malloc(size);
    memset(p, 0, size);
    p->offset = (short*)((char*)swc + sizeof(swc)); // array of shorts begins immediately after the struct
    p->values = (char*)((char*)swc + sizeof(swc) + items * sizeof(short)); // array of chars begins immediately after the array of shorts
    return p;
}
swc *new_swc (int m, int n) {
    swc *p;
    p = malloc (sizeof (*p) + m * sizeof (p->offset[0]) + n * sizeof (p->values[0]);
    p->offset = (short *) &p[1];
    p->values = (char *) &p->offset[m];
    return p;
}