无法访问2维动态分配的数组

时间:2019-03-04 09:16:03

标签: c multidimensional-array malloc

我正在尝试对可变大小的数组进行动态内存分配。函数“ ft_ultimate_range”似乎起作用,但是,当我尝试访问并打印每个数组的数组的值时,会出现问题。它会发出以下分段错误信号:11,当使用GCC编译时,或者使用[http://pythontutor.com/c][1]表示“下标值既不是数组,也不是指针,也不是向量”。我知道这与指针的使用或滥用有关……嗯

SIGINT

...朝着正确方向的一点指针将不胜感激。

3 个答案:

答案 0 :(得分:2)

好吧,很明显,您对如何从ft_ultimate_range()main()返回已分配的网格( pointer-to-pointer-to-int )非常迷惑。 / p>

首先,您不需要将range作为参数传递给ft_ultimate_range()。相反,使返回类型为int **,并在int **range中声明ft_ultimate_range(),然后分配len指针,然后为每个指针分配len整数,并分配值然后返回range并将其分配给arr中的main(),例如

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

/* allocate a grid of [n][n] with numbers ranging max-min */
int **ft_ultimate_range (int min, int max)
{
    int len = max - min,
        **range = NULL,
        count = min;

    /* allocate len pointers */
    range = malloc (len * sizeof * range);
    if (!range) {           /* validate EVERY allocation */
        perror ("malloc-range");
        return NULL;
    }

    /* allocate len int per-pointer */
    for (int i = 0; i < len; i++) {
        range[i] = malloc (len * sizeof *range[i]);
        if (!range[i]) {    /* validate alloation */
            perror ("malloc-range[i]");
            while (i--)             /* free previously allocated rows */
                free (range[i]);    /* free pointers */
            free (range);
            return NULL;
        }
    }

    /* assign values to allocated memory location */
    for(int i = 0; i < len; i++) {
        for(int j = 0; j < len; j++) {
            range[i][j] = count++;
        }
        count = min;
    }

    return range;
}

注意:您必须验证所有分配...)

main()中,您不需要ptr,您所需要的只是int**指针,您可以将ft_ultimate_range()的返回值分配给例如

int main (void) {

    int n = 6 - 3;
    int **arr;

    arr = ft_ultimate_range (3, 6);
    if (!arr)       /* validate return */
        return 1;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf (" %d", arr[i][j]);
        }
        putchar ('\n');
        free (arr[i]);
    }
    free (arr);

    return 0; 
} 

注意:同样,您必须在盲目遍历值之前验证ft_ultimate_range()的返回值(如果分配失败,则不会出现这些值)。

使用/输出示例

$ ./bin/alloc_a_grid
 3 4 5
 3 4 5
 3 4 5

内存使用/错误检查

在您编写的任何动态分配内存的代码中,对于任何分配的内存块,您都有2个职责:(1)始终保留指向起始地址的指针因此,(2)当不再需要它时可以释放

当务之急是使用一个内存错误检查程序来确保您不会尝试访问内存或在已分配的块的边界之外/之外进行写入,不要试图以未初始化的值读取或基于条件跳转,最后,以确认您释放了已分配的所有内存。

对于Linux,valgrind是正常选择。每个平台都有类似的内存检查器。它们都很容易使用,只需通过它运行程序即可。

$ valgrind ./bin/alloc_a_grid
==29026== Memcheck, a memory error detector
==29026== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==29026== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==29026== Command: ./bin/alloc_a_grid
==29026==
 3 4 5
 3 4 5
 3 4 5
==29026==
==29026== HEAP SUMMARY:
==29026==     in use at exit: 0 bytes in 0 blocks
==29026==   total heap usage: 4 allocs, 4 frees, 60 bytes allocated
==29026==
==29026== All heap blocks were freed -- no leaks are possible
==29026==
==29026== For counts of detected and suppressed errors, rerun with: -v
==29026== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认已释放已分配的所有内存,并且没有内存错误。

仔细检查一下,如果还有其他问题,请告诉我。

答案 1 :(得分:1)

这里:

int **ptr, *arr;
arr = ft_ultimate_range(ptr, 3, 6);

ptr为NULL /现在尚未初始化。您不能分配这个。 malloc必须之前调用函数ft_ultimate_range。此处:printf("%d", ptr[i][j]);NULL[i][j]

然后您就可以在功能**ptr中释放ft_ultimate_range

希望获得帮助。

答案 2 :(得分:0)

int **ptr, *arr;
此时

ptr未初始化 。它的值为不确定

arr = ft_ultimate_range(ptr, 3, 6);

始终将未初始化的值传递给函数是错误的。如果您希望该函数将其初始化,那就错了。继续阅读pass by value

ptr = range;

此分配是错误的。您应该已经收到关于它的编译器警告。如果没有,请尽快升级编译器。永远不要忽略警告。用带有警告的程序玩弄玩具是浪费时间。

for(int i = 0; i < len; i++) {
  free(range[i]);
}
free(range);

这时,程序中的每个指针均无效。取消引用它们是不确定的行为。

尚不清楚您的程序应该返回什么。无论如何,您都不使用返回值。

我建议将函数的签名更改为此:

int** ft_ultimate_range(int min, int max)

尝试适应此模具中要执行的操作。