C语言实现变长数组

struct MyData 
{
    int nLen;
    char data[0];
};        

 开始没有理解红色部分的内容,上网搜索下,发现用处很大,记录下来。
         
         在结构中,data是一个数组名;但该数组没有元素;该数组的真实地址紧随结构体MyData之后,而这个地址就是结构体后面数据的地址(如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容);这种声明方法可以巧妙的实现C语言里的数组扩展。
         实际用时采取这样:
         struct MyData *p = (struct MyData *)malloc(sizeof(struct MyData )+strlen(str))
         这样就可以通过p->data 来操作这个str。

         示例:
#include <iostream>

using namespace std;

struct MyData 
{
    int nLen;
    char data[0];
};

int main()
{
    int nLen = 10;
    char str[10] = "123456789";

    cout << "Size of MyData: " << sizeof(MyData) << endl;

    MyData *myData = (MyData*)malloc(sizeof(MyData) + 10);
    memcpy(myData->data,  str, 10);

    cout << "myData's Data is: " << myData->data << endl;

    free(myData);

    return 0;
}
         输出:
Size of MyData: 4
myData's Data is: 123456789         
由于数组没有元素,该数组在该结构体中分配占用空间,所以sizeof(struct Mydata) = 4。
         malloc申请的是14个字节的连续空间,它返回一个指针指向这14个字节,强制转换成struct INFO的时候,前面4个字节被认为是Mydata结构,后面的部分拷贝了“123456789”的内容。

 转自:http://blog.youkuaiyun.com/maopig/article/details/7243646

### 三、C语言中可变长数组(VLA)的使用和特性 可变长数组(Variable Length Array,简称VLA)是C99标准引入的一项特性,允许在运行时动态指定数组的大小。与C99之前的数组不同,VLA的大小可以是一个在运行时确定的表达式,而不再局限于编译时常量或常量表达式。这种机制在某些场景下提供了更高的灵活性和便利性。 在使用VLA时,数组的大小由一个变量或表达式指定,该表达式在运行时被求值,从而决定数组的实际大小。例如: ```c #include <stdio.h> void test(int len) { int array[len]; // 可变长数组 for (int i = 0; i < len; i++) { array[i] = i; printf("array[%d] = %d\n", i, array[i]); } } int main() { int len = 5; test(len); return 0; } ``` 上述代码中,`array` 是一个可变长数组,其大小由变量 `len` 决定。这种方式使得在函数中定义数组时,无需提前知道数组的具体大小,而是根据程序运行时的输入或状态动态调整[^2]。 --- ### 四、VLA的内存分配机制 尽管VLA的大小在运行时确定,但其内存分配仍然是在栈上完成的,而不是在堆上。这意味着VLA的生命周期与函数调用相关,函数返回后,数组的内存将自动释放。这种分配方式与使用 `malloc` 和 `free` 手动管理内存的动态数组不同,避免了内存泄漏的风险[^1]。 此外,VLA的大小一旦确定,就不能在运行时更改。因此,它本质上仍然是一个静态数组,只是其大小的确定时间从编译期推迟到了运行期。只要在数组分配内存之前确定了长度,就可以满足大多数需要动态大小数组的场景[^1]。 --- ### 五、VLA的局限性与争议 尽管VLA提供了便利,但在某些环境中,其使用受到了限制。例如,Linux内核开发者已经决定在未来版本中不再支持VLA,因为它们可能导致栈溢出等问题。在内核开发中,栈空间有限,使用VLA可能会导致不可预测的行为,因此倾向于使用更可控的动态内存分配方式[^3]。 另外,VLA的初始化也存在一定的限制。例如,不能使用初始化列表来初始化一个VLA,因为数组的大小在编译时未知。此外,试图将VLA的所有元素初始化为0时,可能会导致编译错误,除非使用显式的循环进行赋值。 --- ### 六、VLA与动态数组的比较 与动态数组相比,VLA在某些场景下更为简洁和高效。例如,当数组的大小在运行时确定且之后不再改变时,VLA可以避免使用 `malloc` 和 `free` 手动管理内存的繁琐过程。然而,VLA的大小一旦确定,就不能更改,因此不适合需要频繁调整大小的场景。 此外,VLA的使用依赖于编译器对C99标准的支持。尽管GCC等主流编译器支持VLA,但某些编译器(如MSVC)可能不完全支持这一特性,这在跨平台开发中需要特别注意[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值