首页 > 解决方案 > 无法访问动态分配的二维数组

问题描述

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

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

    len = max - min;
    ptr = range;
    // allocate memory **arr
    range = malloc(len * sizeof * range);
    for(int i = 0; i < len; i++) {
          range[i] = malloc(len * sizeof * ptr);
    }

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

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

    return ptr;
}

int main() 
{
  int n;

  n = 6 - 3;
  int **ptr, *arr;
  arr = ft_ultimate_range(ptr, 3, 6);
  // print 
  for(int i = 0; i < n; i++) {
    for(int j = 0; j < n; j++) {
        printf("%d", ptr[i][j]);
    }
  }
  return 0; 
} 

...在正确的方向上的一个小指针将非常感激。

标签: cmultidimensional-arraymalloc

解决方案


好吧,很明显你对如何从to返回分配的网格(指针到指针到 int)非常迷茫。ft_ultimate_range()main()

首先,您不需要range作为参数传递给ft_ultimate_range(). 相反,创建返回类型并int **声明in ,然后分配指针,然后为每个指针分配整数,分配值,然后返回并将其分配给in ,例如int **rangeft_ultimate_range()lenlenrangearrmain()

#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

内存使用/错误检查

在您编写的任何动态分配内存的代码中,对于分配的任何内存块,您有两个责任:(1)始终保留指向内存块起始地址的指针,(2)它可以在没有时被释放更需要。

您必须使用内存错误检查程序来确保您不会尝试访问内存或写入超出/超出分配块的范围,尝试读取或基于未初始化的值进行条件跳转,最后确认释放所有分配的内存。

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

$ 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)

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

如果您还有其他问题,请仔细查看并告诉我。


推荐阅读