我正在试验可变大小数组的动态内存分配。函数"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)
尝试将您要做的任何事情都适合这个模具。