结构的动态数组

时间:2013-12-29 11:37:34

标签: c arrays dynamic struct realloc

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

struct ver{
    double x;
    double y;
};

struct ver *v=NULL;

int main(){

    v=(struct ver*)realloc(v,1*sizeof(struct ver));

    v[0].x=1.444;
    v[0].y=1.555;

    v[1].x=1.333;
    v[1].y=1.222;

    v[3].x=1.111;
    v[3].y=1.777;

    v[8].x=1.999;
    v[8].y=1.888;

    printf("x:%f y:%f \n", v[0].x, v[0].y);
    printf("x:%f y:%f \n", v[1].x, v[1].y);
    printf("x:%f y:%f \n", v[3].x, v[3].y);
    printf("x:%f y:%f \n", v[8].x, v[8].y);
}

结果是:

 x:1.444000 y:1.555000 
 x:1.333000 y:1.222000 
 x:1.111000 y:1.777000 
 x:1.999000 y:1.888000

我不应该得到分段错误吗?它忽略了realloc。 我想创建一个结构数组,我想每次扩展1个数组单元格。

4 个答案:

答案 0 :(得分:2)

您正在呼叫realloc分配一个条目。访问v[0]之外的任何内容未定义的行为 可能导致崩溃,或者可能不会。

从技术上讲,像你这样定义main(没有任何参数,甚至不是void)也是C中的未定义行为。你要么必须用void作为参数声明它,或intchar**

答案 1 :(得分:1)

使用realloc指针调用NULL是明确定义的行为。所以v指向足够的内存,只有一个struct ver。

v[1]没有产生分段错误的原因:这样的错误不一定要发生 - 你可以幸运...也许realloc也会给你更多的记忆要求16个字节。

答案 2 :(得分:1)

如果您正在访问的地址后面没有内存,则只会出现分段错误。这在物理意义上意味着,段错误首先由硬件而非软件发出信号。现在,物理内存映射总是以完整页面的形式发生。在大多数硬件上都是4 kiB。您从realloc()请求的大小只有16个字节。

当然,realloc()返回的地址后面必须有内存。因此,您的结构周围必须至少有4080个地址,这些地址在硬件眼中与属于结构本身的16个地址一样有效。这意味着硬件无法向您的操作系统发出可能有问题的信号,并且您的操作系统无法向您发送分段错误。如果您尝试访问v[1000],可能会遇到段错误,但即使这样也不确定。

这并不意味着您可以访问这些地址,这只意味着您在访问它们时不能依赖段错误。可能有其他分配可能会破坏,或者更糟糕的是,可能存在信息,malloc使用这些信息来确定使用哪些内存区域,哪些内存区域不使用。如果您访问realloc()请求的区域之外的任何地址,则您的程序具有未定义的行为,并且可能发生任何

答案 3 :(得分:0)

有时malloc从操作系统中获取一大块(因此可以在以后使用它),而无需进行上下文切换。

这很贵。

所以你很幸运