下面是我如何声明数组
const int SIZE = 128;
char line[SIZE];
char **lineArray = NULL;
char **lineArray = malloc(count * sizeof(char*));
for (int i = 0; i < count; ++i) {
lineArray[i] = (char *)malloc(SIZE* sizeof(char*));
}
下面是我尝试清除它的地方。..
for (int i = 0; i < count; i++ )
{
free(lineArray[i]); <<- program dies here
}
free(lineArray);
我当然看了其他一些有同样问题的问题,我想我可能在某些情况下没有使用strcopy,但没有。看起来很光明正大strcpy(*(lineArray+i), line);
是我写的唯一时间。
说实话,我这周只学了指针和一堆其他的东西,我看了我的讲座视频,说实话,它没有那么没用。
2条答案
按热度按时间jpfvwuh41#
1.如果你的代码不能编译,就不要强制转换
malloc
的结果,这意味着你正在使用C++编译器编译C代码,这是不正确的。char **lineArray
不是一个2D数组的指针。要分配2D数组,您需要使用pointer to array
const int SIZE = 128;
不是一个常量表达式,并且您的line
将是一个VLA,并非所有编译器都支持它(例如msvc不支持它)。1.请使用正确的型号。它是
size_t
而不是int
vuktfyat2#
请注意,C在非常低的水平上运行。您实际上并不像其他编程语言那样使用数组。在这里,它们可能更愿意被理解为列表。
在C中,更多地从汇编器的Angular 来看待它。C中的每个数组基本上就是一个指针。如果使用方括号,则指定相对于此指针的偏移量。你要做的就是计算新的内存地址:
因此,这里要实现的并不是一个二维数组,而是一个充满指向其他内存位置的指针的数组。这些存储器位置中的每一个可以是任何大小,如果它们存在的话。
我给予两个例子:
动态方式(无2D-Array)
如果我想和你做同样的事,我会这么做。这不是2D数组!它是一个指向指针数组的指针。因此,您保留了可以包含这些指针的内存,但它们可能根本不存在。
静态方式(2D-Array)
2D数组可以被认为是一个表。有固定数量的行和列。这也是您的实现的不同之处。当你处理指向指针的指针时,行的数量是固定的,但是每行的列数是任意的。实现“真实的”2D阵列可以如下完成:
哪种方式更好?
这完全取决于你所做的工作的复杂性。在某些情况下,你必须依赖可变长度。但是,每个 *alloc调用都会产生一定的开销。大型环境中的内存管理绝不是微不足道的,因此您要尽量保持保留的数量相当小。通常,您会保留较大的连续内存块,并根据需要获取更多。只要比较上面的两个例子,你就会发现在处理一个单一的预订时要做和考虑的事情明显少得多。
当然,以细粒度的方式管理内存有其优点。您可以在有限的资源下非常高效,但这也增加了复杂性。