C语言 第一次使用 Malloc,程序崩溃



该程序旨在接收"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);
    }
}

你有三个问题。首先是你没有为"数组"分配足够的条目:

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将指向您读取的最后一个字符串,因此namespointerToNames[n - 1]将指向同一字符串。


另外两个问题包括您没有释放首次分配的实际pointerToNames内存。并且您不应该使用gets(它早已被弃用,甚至在最新标准中删除)。请改用fgets(或gets_s)。

另外,不要投掷malloc的回归。

您的第一个malloc旨在为指向字符的指针分配内存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循环从0N-1,而不是NpointerToNames[N]不是有效的数组元素。

最新更新