该计划旨在接收'n'个学生及其姓名并对其进行排序 (没有到分拣部分)。 我无法弄清楚为什么我的程序在测试时崩溃了。 这是代码:
#include<stdio.h>
#include <stdlib.h>
#define MaxNameLen 100
int main() {
int n;
scanf("%d", &n);
char *names;
char **pointerToNames = (char **) malloc(n * sizeof(char));
if (pointerToNames == NULL)
return 0;
int i;
for (i = 0; i <= n; i++) {
names = (char *) malloc(MaxNameLen);
gets(names);
pointerToNames[i] = names;
}
for (i = 0; i < n; i++) {
free(pointerToNames[i]);
free(names);
}
}
答案 0 :(得分:5)
你有三个问题。第一个是你没有为“数组”分配足够的条目:
malloc(n * sizeof(char))
应该是
malloc(n * sizeof(char*))
第二个问题是阅读循环:
for (i = 0; i <= n; i++) {
这里的循环条件会导致你循环一次到多次,导致你写出超出你分配的数量(如果你解决了第一个问题)。循环中的条件应该是i < n
,就像在下一个循环中一样。
第三个问题是你在循环中重复释放最后一个字符串
for (i = 0; i < n; i++) {
free(pointerToNames[i]);
free(names);
}
当您在上面的循环中将names
分配给pointerToNames[i]
时,完成该循环时names
将指向您读取的最后一个字符串,因此names
和{{ 1}}将指向相同的字符串。
另外两个问题包括你没有释放你最初分配的实际pointerToNames[n - 1]
内存。并且您不应该使用pointerToNames
(它已经被弃用,甚至在最新标准中被删除)。请改用fgets
(或gets_s
)。
答案 1 :(得分:1)
你的第一个malloc
意味着为chars的N
指针分配内存,但是你正在分配N
个字符,这可能要少得多。
更改此行:
char **pointerToNames = (char **) malloc(n * sizeof(char));
对此:
char **pointerToNames = malloc(n * sizeof(*pointerToNames));
此外:
for (i = 0; i < n; i++) {
free(pointerToNames[i]);
free(names);
这释放了指示索引的内存,但你也释放了names
,这恰好是你用来分配内存的临时指针,然后你为每个eement分配了当前值name
。因此,无需免费names
。
也许您觉得更容易将第二部分(为数组的每个元素分配内存的代码)更改为:
for (i = 0; i < n; i++) {
pointerToNames[i] = malloc(MaxNameLen);
if (pointerToNames[i])
fgets(pointerToNames[i], MaxNameLen-1, stdin);
}
因此不再使用names
而是使用gets()
代替fgets()
。请注意,for
循环从0
转到N-1
,而不是N
。 pointerToNames[N]
不是有效的数组元素。