我在纠结指针和它们的分配。我想知道我的分配是否正确,否则应该怎么做。另外,我得到了关于fgets和puts函数的警告,但我认为这与错误的分配有关。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
const int n = 30, m = 30;
struct employer {
char *name[3][1];
char *pass[n][m];
int *ID;
};
int main() {
struct employer admin;
i = 0;
for (i = 0; i < 3; i++) {
admin.name[i][1] = (char*)calloc(1, n);
}
for (i = 0; i < 3; i++) {
fgets(admin.name[i][1], n, stdin);
puts(admin.name[i][1]);
}
return 0;
}
以下是我得到的警告:
- 数组索引1超过数组的末尾(包含1个元素)[-Warray-bounds]";
- 数组索引1超过数组的末尾(包含1个元素)[-Warray-bounds]";
- 数组索引1超过数组的末尾(包含1个元素)[-Warray-bounds]";
它们分别与I分配的线路、fgets fcn线路和puts fcn线路有关。你能告诉我我错在哪里吗?
2条答案
按热度按时间ckocjqey1#
代码的三个问题。首先,您在
main
中使用了i
,但没有声明它。第二,您正在访问长度为1
的数组中的索引1
。由于数组是从0
开始索引的,所以应该使用索引0
。第三,C中数组的维数必须是常量表达式。因此,我将const int
声明替换为预处理器指令来定义N
和M
。这是值得怀疑的,为什么你会想要一个长度为1的数组。这不会让你得到任何简单的
char *name[3]
。在实践中,您应该在假设分配成功之前检查分配是否成功。
您还需要
free
动态分配的任何内存。对于这样一个小程序,很可能你运行的操作系统会在程序停止时自动释放内存,但这并不是一个坏习惯。当然,对于这样一个已知数组边界的简单程序,是否真的需要动态分配是值得怀疑的。
xwbd5t1u2#
我得到了关于fgets和puts函数的警告,但我认为这与错误的分配有关。
不,它与动态内存分配无关
char *name[3][1];
只有一列。您尝试在使用索引
1
时访问第二列**C *(和 C++)索引从
0
开始要访问第一列,您需要:
以下不是有效的
C
。它是带有GCC扩展的 C++,如果你使用 *
C
* 语言编译器,它将无法编译。还有这个:
不会编译。您需要定义
i
另外在C语言中不强制转换结果的
malloc
家族函数。记住释放已分配的内存!!!