二维动态数组(在C的realloc) [英] two-dimensional dynamic array (realloc in c)

查看:311
本文介绍了二维动态数组(在C的realloc)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从输入两个双数装载到二维数组由每一个用户输入dynamicaly realocated。

I am trying to load two double numbers from input to two-dimensional array dynamicaly realocated by every user input.

#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;
}

计划失败,每一次我试图挽救值到数组(可能是内存的问题)的时间。它被编译没有问题。

Program fails every time i try to save value into array (probably memory problem). It is compiled without problems.

谁能告诉我如何正确的realloc新的数组?

Can anyone show me how to properly realloc new array ?

感谢您的帮助。

推荐答案

您有几个问题。


  1. 您不要初始化数= 0; 计数= 0 所以你必须在一个不确定的值变量启动第一个的realloc()呼叫。这是个坏消息。

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

  3. scanf()的调用不正确;你是不是传递指针给它。

  1. You don't initialize numbers = 0; or count = 0 so you have an indeterminate value in the variable before you start the first realloc() call. That's bad news.
  2. The more major problem is that you've misunderstood the memory allocation that's needed to simulate a 2D-array.
  3. Your scanf() call is incorrect; you are not passing pointers to it.

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] |
+------------+     +---------------+---------------+

您确实需要存储在数字指针,指针数组,的数组双。此刻,你是不是对分配指针数组的空间,这是你的烦恼的原因。双打的阵列可以是连续的或不连续的(即,每一行可被单独分配,但行内,分配必须是连续的,当然)

You actually need the pointer stored in numbers, the array of pointers, and the array of double. At the moment, you are not allocating the space for the array of pointers, and this is the cause of your troubles. The array of doubles can be contiguous or non-contiguous (that is, each row may be separately allocated, but within a row, the allocation must be contiguous, of course).

工作code:

#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;
}

注:这仍然是不好code。具体地说,增量逐酮每个时间机构中使用的是坏的。梅梅指针= realloc的(指针,newsize); 是太糟糕;如果分配失败,你无法释放previously分配的内存。您应该使用 NEWPTR = realloc的(指针,newsize); 其次是内存检查前指针= NEWPTR;

NB: This is still not good code. In particular, the increment-by-one-each-time mechanism in use is bad. The meme pointer = realloc(pointer, newsize); is bad too; you can't release the previously allocated memory if the allocation fails. You should use newptr = realloc(pointer, newsize); followed by a memory check before 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 没有正式运行,但我相信这将是确定。

Not formally run under valgrind, but I'm confident it would be OK.

什么是节约投入阵不知道有多少投入要存储的最佳解决方案?或者,也许它只是这个复杂的用C相比,Java或PHP?

What is the best solution for saving inputs into array without knowing how many inputs I have to store ? Or maybe it is just this complicated in C compared to Java or PHP?

除了部分一个单位,这是关于它的方式已在C工作,至少如果你想索引使用两个指标的结果:号码[I] [0 ] 等。

Except for the 'increment by one' part, this about the way it has to work in C, at least if you want to index into the result using two indexes: numbers[i][0] etc.

另一种方法是分配空间,你在做(除了不是'一个递增'),然后使用前pression索引数组:双*号=。 ..; 号码[I * 2 + 0] 号码[I * 2 + 1] 你的情况,但在一个阵列中的更一般的情况 NCOLS 列,访问第二行 I 和列Ĵ使用号码[我* NCOLS + J] 。你交易号码[I] [J] 对内存分配的增加并发症的标记方便。 (注意,那就是,对于这一机制,数组的类型是双*号; 而不是双**号; ,因为它是在你的code)

An alternative would be to allocate the space as you were doing (except not 'incrementing by one'), and then using an expression to index the array: double *numbers = ...; and numbers[i*2+0] and numbers[i*2+1] in your case, but in the more general case of an array with ncols columns, accessing row i and column j using numbers[i*ncols + j]. You trade the notational convenience of numbers[i][j] against the increased complication of memory allocation. (Note, too, that for this mechanism, the type of the array is double *numbers; instead of double **numbers; as it was in your code.)

'由一个增量'避免这些替代品通常使用的空间量加倍的每个分配。您可以决定做与的初始分配的malloc()键,随后使用的realloc()来增加空间,或你可以只使用的realloc()知道,如果传入的指针为NULL,则它会做等同的malloc()。 (事实上​​,的realloc()是一个完整的内存分配的管理包在一个函数;如果大小为0调用它,它会免费() 内存而不是分配。)(AB)是否使用 realloc的人辩论()一样,是一个好主意或没有。由于它是由C89 / C90和C标准更高版本的保障,这是足够安全,而且减少了一个函数调用,所以我倾向于只使用的realloc()

The alternatives avoiding 'increment by one' typically use a doubling of the amount of space on each allocation. You can decide to do an initial allocation with malloc() and subsequently use realloc() to increase the space, or you can use just realloc() knowing that if the pointer passed in is NULL, then it will do the equivalent of malloc(). (In fact, realloc() is a complete memory allocation management package in one function; if you call it with size 0, it will free() the memory instead of allocating.) People debate whether (ab)using realloc() like that is a good idea or not. Since it is guaranteed by the C89/C90 and later versions of the C standard, it is safe enough, and it cuts out one function call, so I tend to use just 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;
}

这code与的valgrind 检查没有问题;分配的所有code的释放。注意使用功能 free_numbers()的释放内存错误的路径。当它像这里的main()函数运行并不重要,但绝对是重要的,当工作中,可能会被很多程序使用的功能已经完成。

This code was checked with valgrind without problems; all code allocated was freed. Note the use of the function free_numbers() to release the memory in the error paths. That's not critical when it is running in a main() function like here, but is definitely important when the work is done in a function that may be used by many programs.

这篇关于二维动态数组(在C的realloc)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆