我试图从输入加载两个双数字动态地由每个用户输入重新定位的二维数组.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int count;
double number1, number2, **numbers;
while (scanf("%lf,%lf", number1, number2) != EOF) {
count++;
numbers = (double**) realloc(numbers, count * 2 * sizeof (double));
if (numbers == NULL) {
exit(1);
}
numbers[count][0] = number1;
numbers[count][1] = number2;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
每次我尝试将值保存到数组(可能是内存问题)时程序失败.它编译没有问题.
任何人都可以告诉我如何正确地重新分配新阵列?
谢谢你的帮助.
Jon*_*ler 16
你有几个问题.
numbers = 0;或者count = 0在变量中有一个不确定的值realloc().这是个坏消息.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] |
+------------+ +---------------+---------------+
Run Code Online (Sandbox Code Playgroud)
实际上你需要存储numbers指针,指针数组和数组double.目前,您没有为指针数组分配空间,这是您遇到麻烦的原因.双精度数组可以是连续的或非连续的(也就是说,每行可以单独分配,但在一行内,分配当然必须是连续的).
工作代码:
#include <stdio.h>
#include <stdlib.h>
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;
}
Run Code Online (Sandbox Code Playgroud)
注意:这仍然不是很好的代码.特别是,每次使用的逐个增量机制都很糟糕.模因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
Run Code Online (Sandbox Code Playgroud)
输出数据:
( 12.34, 23.45)
( 34.56, 45.67)
( 56.78, 67.89)
( 78.90, 89.01)
Run Code Online (Sandbox Code Playgroud)
没有正式运行valgrind,但我相信它会没事.
在不知道我必须存储多少输入的情况下,将输入保存到阵列中的最佳解决方案是什么?或者,与Java或PHP相比,它可能只是在C中这么复杂?
除了'一个一个'部分,这是关于它必须在C中工作的方式,至少如果你想使用两个索引索引结果:numbers[i][0]等等.
另一种方法是分配作为你正在做的空间(除了不"由一个递增"),然后使用表达式来索引数组:double *numbers = ...;和numbers[i*2+0]和numbers[i*2+1]你的情况,但在与阵列的更一般的情况ncols列访问行i和列j使用numbers[i*ncols + j].你交换了numbers[i][j]符合内存分配复杂性的符号方便性.(另请注意,对于此机制,数组的类型double *numbers;不是double **numbers;代码中的类型.)
避免"逐一增加"的替代方案通常使用每次分配的空间量的两倍.您可以决定使用malloc()并随后使用realloc()来增加空间,或者您可以使用只realloc()知道如果传入的指针是NULL,那么它将执行相当于malloc().(事实上,realloc()在一个函数中是一个完整的内存分配管理包;如果你用0大小调用它,它将free()是内存而不是分配.)人们争论是否(ab)使用realloc()这样是一个好主意.由于它是由C89/C90及更高版本的C标准保证的,它足够安全,并且它会切断一个函数调用,所以我倾向于使用realloc():
#include <stdio.h>
#include <stdlib.h>
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;
}
Run Code Online (Sandbox Code Playgroud)
这个代码valgrind没有问题; 分配的所有代码都已释放.请注意使用该函数free_numbers()释放错误路径中的内存.当它在main()像这里这样的函数中运行时,这并不重要,但是当工作在可能被许多程序使用的函数中完成时,这绝对是重要的.
| 归档时间: |
|
| 查看次数: |
22771 次 |
| 最近记录: |