4

所以,我在为char ***类型变量分配内存时遇到了麻烦。我的目标是创建一个字符串矩阵,我目前用于内存分配的代码如下:

char ***matrix;

matrix = calloc(n*MAX_STR, sizeof(char**));
for(z = 0; z < n; z++) {
    matrix[z] = calloc(n, sizeof(char*));
    for(i = 0; i < MAX_STR; i++) {
        matrix[z][i] = calloc(MAX_STR, sizeof(char));
    }
}

我已经成功地为一个字符串数组分配了内存,使用这个:

char **list;
list = calloc(n, sizeof(char *));
for (j = 0; j < n; j++){
list[j] = calloc(MAX_STR, sizeof(char));
}

但我现在遇到了矩阵问题。

在 Valgrind 上使用 --leak-check=full 运行程序会给我以下消息:

==5126== Invalid write of size 8
==5126==    at 0x400B9F: createmat (proj.c:100)
==5126==    by 0x401598: main (proj.c:237)
==5126==  Address 0x5210878 is 0 bytes after a block of size 72 alloc'd
==5126==    at 0x4C2ABB4: calloc (vg_replace_malloc.c:593)
==5126==    by 0x400B52: createmat (proj.c:98)
==5126==    by 0x401598: main (proj.c:237)

我想弄清楚为此分配内存,因为在 C 中的内存管理方面我仍然是初学者。任何帮助将不胜感激,谢谢。

编辑:矩阵应该存储 n 个字符串数组,它们对应于输入的行(fgets稍后读取),并且每个数组分配该行具有的任何数量的单词,每个单词(读取,每个字符串)具有最多MAX_STR字符数。 n是从输入中读取的变量,MAX_STR而是程序中定义的常量。

4

3 回答 3

7

字符串矩阵或/ 3D 字符数组:

假设您需要N矩阵,每个矩阵可以存储长度R的字符串,那么您应该为循环分配内存,如下所示: MAX_STR-1

char ***matrix;

matrix = calloc(N, sizeof(char**)); 
for(z = 0; z < N; z++) { 
    matrix[z] = calloc(R, sizeof(char*));
    for(i = 0; i < R; i++) {
        matrix[z][i] = calloc(MAX_STR, sizeof(char));
    }
}

它将创建如下矩阵:

matrix
+-------------------+------------------+-----------------------+
| 0                 | 1                | 2                     |
+-------------------+------------------+-----------------------+        
 |                           |                        |
 ▼                           ▼                        ▼
+--+    +----------+       +--+    +----------+     +--+    +----------+
|0 +---►| MAX_STR  |       |0 +---►| MAX_STR  |     |0 +---►| MAX_STR  |
+--+    +----------+       +--+    +----------+     +--+    +----------+
|1 +---►| MAX_STR  |       |1 +---►| MAX_STR  |     |1 +---►| MAX_STR  |
+--+    +----------+       +--+    +----------+     +--+    +----------+
|2 +---►| MAX_STR  |       |2 +---►| MAX_STR  |*    |2 +---►| MAX_STR  |
+--+    +----------+       +--+    +----------+     +--+    +----------+
|3 +---►| MAX_STR  |       |3 +---►| MAX_STR  |     |3 +---►| MAX_STR  |
+--+    +----------+       +--+    +----------+     +--+    +----------+
|4 +---►| MAX_STR  |       |4 +---►| MAX_STR  |     |4 +---►| MAX_STR  |
+--+    +----------+       +--+    +----------+     +--+    +----------+
|5 +---►| MAX_STR  |       |5 +---►| MAX_STR  |     |5 +---►| MAX_STR  |
+--+    +----------+       +--+    +----------+     +--+    +----------+
|6 +---►| MAX_STR  |       |6 +---►| MAX_STR  |     |6 +---►| MAX_STR  |
+--+    +----------+       +--+    +----------+     +--+    +----------+
|7 +---►| MAX_STR  |       |7 +---►| MAX_STR  |     |7 +---►| MAX_STR  |
+--+    +----------+       +--+    +----------+     +--+    +----------+
 ^        ^ 
 |        |
 |        matrix[z][i]
 matrix[z]

这里 N = 3,
R = 8

它的 char 3D 大小数组matrix[N][R][MAX_STR]

假设,如果有人想打印我*在图中标记的字符串,即第二个数组中的第三个字符串,那么他/她需要像这样索引

printf("%s",matrix[1][2]);

尽管接受了答案,但我正在更新我的答案,以便将来会发现它有帮助

于 2013-05-13T12:36:41.893 回答
5

假设您要为n数组分配存储空间,每个数组都有n字符串,每个最长MAX_STR,代码中有几个错误

matrix = calloc(n*MAX_STR, sizeof(char**));

应该

matrix = calloc(n, sizeof(char**));

for(i = 0; i < MAX_STR; i++) {

应该

for(i = 0; i < n; i++) {

再详细一点,

matrix = calloc(n*MAX_STR, sizeof(char**));
for(z = 0; z < n; z++) {

似乎错了。您分配n*MAX_STR元素但仅使用n它们

matrix[z] = calloc(n, sizeof(char*));
for(i = 0; i < MAX_STR; i++) {

也是有问题的并且是错误的n<MAX_STR。(您分配n元素然后写入MAX_STR它们。)

最后,根据您是否考虑MAX_STR为空终止符包含空间,您可能需要更改

matrix[z][i] = calloc(MAX_STR, sizeof(char));

matrix[z][i] = calloc(MAX_STR+1, 1);
于 2013-05-13T12:29:42.860 回答
2

正如您所说,您可以使用以下代码成功创建一个字符串数组:

char **list;
list = calloc(n, sizeof(char *));
for (j = 0; j < n; j++){
list[j] = calloc(MAX_STR, sizeof(char));
}

现在,您需要一个字符串数组,所以它应该是:

char ***matrix;

matrix = calloc(n, sizeof(char**)); //This creates space for storing the address of 'n' array of strings 
for(z = 0; z < n; z++) { //This loop creates the 'n' array of strings.
    matrix[z] = calloc(n, sizeof(char*));
    for(i = 0; i < n; i++) {
        matrix[z][i] = calloc(MAX_STR, sizeof(char));
    }
}

因此,基本上,在第二个代码中,您只是为存储“n”个列表创建空间。希望这可以说清楚。

于 2013-05-13T12:34:35.363 回答