c语言二维动态数组 realloc,二维动态数组(c中的realloc)

您没有初始化numbers = 0;或count = 0,因此在开始第一次realloc()调用之前,您在变量中有一个不确定的值。这是个坏消息。

更主要的问题是你误解了模拟2D阵列所需的内存分配。

您的scanf()来电不正确;你没有传递指针。

醇>

ASCII艺术

+---------+

| numbers |

+---------+

|

v

+------------+ +---------------+---------------+

| numbers[0] |---->| numbers[0][0] | numbers[0][1] |

+------------+ +---------------+---------------+

| numbers[1] |---->| numbers[1][0] | numbers[1][1] |

+------------+ +---------------+---------------+

| numbers[2] |---->| numbers[2][0] | numbers[2][1] |

+------------+ +---------------+---------------+

实际上你需要存储在numbers中的指针,指针数组,和 double数组。目前,您没有为指针数组分配空间,这是您遇到麻烦的原因。双精度数组可以是连续的也可以是非连续的(也就是说,每行可以单独分配,但在一行中,分配必须是连续的)。

工作代码:

#include

#include

int main(void)

{

int count = 0;

double number1, number2;

double **numbers = 0;

while (scanf("%lf,%lf", &number1, &number2) != EOF)

{

numbers = (double **) realloc(numbers, (count + 1) * sizeof(*numbers));

if (numbers == NULL)

exit(1);

numbers[count] = (double *)malloc(2 * sizeof(double));

if (numbers[count] == 0)

exit(1);

numbers[count][0] = number1;

numbers[count][1] = number2;

count++;

}

for (int i = 0; i < count; i++)

printf("(%8.2f, %8.2f)\n", numbers[i][0], numbers[i][1]);

for (int i = 0; i < count; i++)

free(numbers[i]);

free(numbers);

return 0;

}

注意:这仍然不是很好的代码。特别是,每次使用的逐个增量机制都很糟糕。模因pointer = realloc(pointer, newsize);也很糟糕;如果分配失败,则无法释放先前分配的内存。您应该使用newptr = realloc(pointer, newsize);,然后在pointer = newptr;之前进行内存检查。

输入文件:

12.34,23.45

34.56,45.67

56.78,67.89

78.90,89.01

输出数据:

( 12.34, 23.45)

( 34.56, 45.67)

( 56.78, 67.89)

( 78.90, 89.01)

未正式在valgrind下运行,但我相信它会没事。

在不知道我必须存储多少输入的情况下,将输入保存到阵列的最佳解决方案是什么?或者,与Java或PHP相比,它可能只是在C中复杂化了吗?

除了'一个一个'部分,这是关于它必须在C中工作的方式,至少如果你想使用两个索引索引结果:numbers[i][0]等。

另一种方法是按照您的方式分配空间(除非“递增1”除外),然后使用表达式索引数组:double *numbers = ...;和numbers[i*2+0]以及{{1在您的情况下,但在更一般的情况下,使用numbers[i*2+1]列的数组,使用ncols访问行i和列j。您将numbers[i*ncols + j]的符号方便性与增加的内存分配复杂性进行了交换。 (另请注意,对于此机制,数组的类型为numbers[i][j],而不是代码中的double *numbers;。)

避免“逐一增加”的替代方案通常使用每次分配的空间量加倍。您可以决定使用double **numbers;进行初始分配,然后使用malloc()来增加空间,或者只使用realloc()知道如果传入的指针是NULL,那么它将会做相当于realloc()。 (实际上,malloc()是一个函数中的完整内存分配管理包;如果用大小0调用它,它将realloc()内存而不是分配。)人们争论是否(ab)使用{ {1}}这样的好主意是不是。由于它是由C89 / C90及更高版本的C标准保证的,它足够安全,并且它会切断一个函数调用,所以我倾向于仅使用free():

realloc()

使用realloc()检查此代码没有问题;分配的所有代码都已释放。请注意使用函数#include

#include

static void free_numbers(double **array, size_t size)

{

for (size_t i = 0; i < size; i++)

free(array[i]);

free(array);

}

int main(void)

{

int count = 0;

double number1, number2;

double **numbers = 0;

double maxnum = 0;

while (scanf("%lf,%lf", &number1, &number2) != EOF)

{

if (count == maxnum)

{

size_t newnum = (maxnum + 2) * 2; /* 4, 12, 28, 60, ... */

double **newptr = (double **)realloc(numbers, newnum * sizeof(*numbers));

if (newptr == NULL)

{

free_numbers(numbers, count);

exit(1);

}

maxnum = newnum;

numbers = newptr;

}

numbers[count] = (double *)malloc(2 * sizeof(double));

if (numbers[count] == 0)

{

free_numbers(numbers, count);

exit(1);

}

numbers[count][0] = number1;

numbers[count][1] = number2;

count++;

}

for (int i = 0; i < count; i++)

printf("(%8.2f, %8.2f)\n", numbers[i][0], numbers[i][1]);

free_numbers(numbers, count);

return 0;

}释放错误路径中的内存。当它在像这里的valgrind函数中运行时,这并不重要,但是当工作在可能被许多程序使用的函数中完成时,这绝对是重要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值