【问题标题】:Invalid pointer in CC中的无效指针
【发布时间】:2013-11-17 04:32:17
【问题描述】:

我提前道歉,但这有点长。

在我的程序中,我读入了学生的信息,但是当我去输出它时,它出来的时候是乱码,然后得到一个指针错误。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct student{
        char *firstName;
        char *lastName;
        char id[10];
        char gender;
        int age;
        double gpa;
};

void main()
{
    int n;
    struct student *classroom;

    printf("How many students?");
    scanf("%d",&n);
    classroom = (struct student*) malloc(n*sizeof(struct student));

    if (classroom == NULL)
    exit(1);

readStudentsInformation(classroom,n);
outputStudents(classroom,n);
printf("The average age is %.2f.\n",averageAge(classroom,n));
printf("The average GPA is %.2f.\n",averageGpa(classroom,n));
sortByLastName(classroom,n);
outputStudents(classroom,n);
sortByID(classroom,n);
outputStudents(classroom,n);
sortByAge(classroom,n);
}

void outputStudents(struct student classroom[], int size)
{

    int i;
    for (i = 0; i < size; i++)
    {
        printf("%15s",classroom[i].firstName);
        printf("%15s:",classroom[i].lastName);
        printf("%14s,",classroom[i].id);
        printf("%3c",classroom[i].gender);
        printf("%5d",classroom[i].age);
        printf("%5.2f",classroom[i].gpa);
    }
}

输入: 有多少学生?2 名字?汤姆 姓氏?阿伦 身份证?2 性别?M 年龄?26 平均绩点?3.9 名字?弗兰克 姓氏?罗伯茨 身份证?1 性别?F 年龄?24 GPA?3.4'

输出:

    Roberts        Roberts:             2,  M   26 3.90                              :             1,  F   24 3.40The average age is 25.00.

平均 GPA 为 3.65。 * 检测到 glibc * ./lab12: munmap_chunk(): 无效指针:0x00007fff30319a90 *

                       :             2,  M   26 3.90Aborted (core dumped)

完整的代码在这里,但我不想复制200行堆栈溢出:http://codepad.org/LYpS6t5z

知道是什么原因造成的吗?

【问题讨论】:

  • munmap_chunk 听起来像是free 的一部分,这意味着您可能损坏了malloc 的内存。
  • 看起来你在用 temp 和你的成员指针做一些奇怪的事情[这至少会泄漏 mallocd 内存,当你释放成员时会出现段错误]
  • valgrind 非常擅长发现这些问题。
  • 您践踏了未分配的内存。就像写到数组的末尾一样。使用 -g 编译,然后运行 ​​valgrind。它会告诉你从某事结束的那一行。
  • 奇怪的东西我的意思是为这些指针分配一个堆栈引用[并且在这个过程中泄漏了释放你的 malloc 内存的所有可能性]

标签: c struct


【解决方案1】:

这是一个概念性错误,您在几个地方都有它

classroom[i].firstName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
if (classroom[i].firstName == NULL)
     exit(1);
classroom[i].firstName = temp;

你想要的是

classroom[i].firstName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
if (classroom[i].firstName == NULL)
     exit(1);
strcpy(classroom[i].firstName, temp); // note this

或者,清理一下:

classroom[i].firstName = malloc(1+strlen(temp)); // note clean up here
if (classroom[i].firstName == NULL)
     exit(1);
strcpy(classroom[i].firstName, temp);

甚至只是

classroom[i].firstName = strdup(temp); // this takes place of all the lines above

这些错误解释了为什么你的 free 失败了。

没有其他事情会在我身上跳出来。

【讨论】:

  • strcmp 比较,你想要strcpy
  • 哦,你是对的,除了我想要strcpy。忘记改了,谢谢。
【解决方案2】:
classroom[i].firstName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
if (classroom[i].firstName == NULL)
    exit(1);
classroom[i].firstName = temp;

您在此处的第二个分配覆盖了 地址,泄漏了 mallocd 内存并在 for 迭代完成后立即使指针无效。 lastName 重复使用相同的缓冲区(具有相同的错误),这就是为什么您看到 Roberts Roberts 而不是实际的名字和姓氏的原因。当您转到free 他们时,他们 (1) 无效并且 (2) 不是由 malloc 制作的,因此您会看到您看到的崩溃。

和其他数组一样,不能通过赋值复制,必须逐字节复制:

size_t len = strlen(temp);
classroom[i].firstName = malloc(1+len);
if (classroom[i].firstName == NULL)
    exit(1);
strncpy(classroom[i].firstname, temp, len);
classroom[i].firstname[len] = '\0';

并且不要转换malloc的结果。

【讨论】:

    【解决方案3】:

    readStudentsInformation 中发生了奇怪的事情,尤其是像

    这样的行

    classroom[i].lastName = temp;

    稍后当您尝试释放此内存时会导致问题

    free(classroom[i].firstName);

    适当的内存处理如下:

    void readStudentsInformation(struct student classroom[], int size)
    {
      int i;
      char temp[50];
    
      for (i = 0; i < size; i++)
      {
        printf("First Name?");
        scanf("%s",temp);
        classroom[i].firstName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
        if (classroom[i].firstName == NULL)
          exit(1);
        /* after mallocing good memory can write in the data.. */
        strcpy(classroom[i].firstName, temp);
    /*    classroom[i].firstName = temp; */
        printf("Last Name?");
        scanf("%s",temp);
        classroom[i].lastName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
        if (classroom[i].lastName == NULL)
          exit(1);
    /*    classroom[i].lastName = temp; */
        strcpy(classroom[i].lastName, temp);
        printf("ID?");
        scanf("%s",classroom[i].id);
        fflush(stdin);
        __fpurge(stdin);
        printf("Gender?");
        scanf("%c",&classroom[i].gender);
        printf("Age?");
        scanf("%d",&classroom[i].age);
        printf("GPA?");
        scanf("%lf",&classroom[i].gpa);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-18
      • 2018-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      相关资源
      最近更新 更多