【发布时间】:2016-02-21 22:23:13
【问题描述】:
我想接收三个任意长度的双精度缓冲区。下面是一个简短的例子
struct Data
{
double *foo[3];
};
int main(void)
{
double bar1[] = {1.0, 2.0, 3.0};
double bar2[] = {1.0, 2.0, 3.0, 4.0};
double bar3[] = {1.0, 2.0, 3.0, 4.0, 5.0};
struct Data *data = (struct Data*)malloc(sizeof(struct Data));
data->foo[0] = bar1;
data->foo[1] = bar2;
data->foo[2] = bar3;
printf("%lf %lf %lf\n", data->foo[0][0], data->foo[0][1], data->foo[0][2]);
printf("%lf %lf %lf %lf\n", data->foo[1][0], data->foo[1][1],
data->foo[1][2], data->foo[1][3]);
printf("%lf %lf %lf %lf %lf\n", data->foo[2][0], data->foo[2][1],
data->foo[2][2], data->foo[2][3], data->foo[2][4]);
return 0;
}
我担心的是,如果我以上述方式 malloc Data 我会冒数据损坏的风险。如果我在不知道大小的情况下在堆上为指向双缓冲区的指针数组(或本质上是任意大小的二维数组)分配内存,那么数据是否受到任何保护?我觉得它有可能覆盖数据。我的这种想法正确吗?这可以编译和打印,但我不确定我是否相信它在更大规模的实现中。
【问题讨论】:
-
在 C 中使用指针时,总是存在损坏的可能性。甚至以 NUL 结尾的字符串也只是一个约定:当你有一个
char *时,你可以在内存中的任何地方前进或后退,直到操作系统告诉你你搞砸了,通常是通过一个段错误。 -
你不应该转换
malloc()的结果。我没有这里的链接,但有充分的理由 - 它可以隐藏警告。 -
好吧,不要覆盖它! ;-)。一个想法是不要将简单的数组作为 foo->Data 成员,而是定义另一个具有 int 作为第一个元素的结构,以保持长度信息。如果这类似于 c++ 向量,那么,好吧..
-
@MadPhysicist 在没有任何指示的情况下,数据损坏的可能性同样大;它只会在以后表现出来,而且可能更微妙。
-
@Talaria 一般来说,您的代码形式没有那么有用。您已经从动态内存中分配了一个
struct Data,但是您将成员数组foo[]的元素设置为指向堆栈上的变量。如果您想从某个函数返回指向以这种方式初始化的struct Data的指针,那将是不好的,因为data->foo中的指针现在将指向无效内存。通常,您需要初始化foo[]的每个元素以指向已分配的动态内存块,然后初始化这些内存块。
标签: arrays c pointers malloc heap-memory