c语言 - 无法访问动态分配的 2 维数组



我正在试验可变大小数组的动态内存分配。函数"ft_ultimate_range"似乎有效,但是,当我尝试访问和打印每个数组数组的值时会出现问题。当使用 GCC 编译时,它表示分段错误:11,或者使用 [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; 
} 

。在正确的方向上一点点指针将不胜感激。

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

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

#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,你所需要的只是你将返回从ft_ultimate_range()分配到的int**指针,例如

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)

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

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

在这里:

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

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

您可以在功能ft_ultimate_range中释放**ptr.

希望这有帮助。

int **ptr, *arr;

此时ptr尚未初始化。它的价值是不确定的。

arr = ft_ultimate_range(ptr, 3, 6);

将未初始化的值传递给函数总是错误的。如果你希望函数能够初始化它,那你就错了。继续按值传递

ptr = range;

这个分配是错误的。您应该已经收到有关它的编译器警告。如果没有,请尽快升级编译器。切勿忽略警告。玩弄一个带有警告的程序是浪费时间。

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

此时,程序中的每个指针都无效。取消引用它们是未定义的行为。

完全不清楚你的程序应该返回什么。无论如何,您都没有使用返回值。

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

int** ft_ultimate_range(int min, int max)

尝试将您要做的任何事情都适合这个模具。

相关内容

  • 没有找到相关文章

最新更新