【问题标题】:May I have some problem with memory allocated分配的内存有问题吗
【发布时间】:2020-11-07 13:34:06
【问题描述】:

我有这段代码,在第一次写入数组(成功的数据写入)之后,我们得到 null 作为消息,我不知道为什么。 我已经尝试了很多东西,请帮助我。 我的代码是:

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

struct course {
int marks;
char *subject;
};



int main(int argc, char *argv[])
{
    struct course *ptr;
    int i, noOfRecords;

    printf("Enter the number of records: ");
    scanf("%d", &noOfRecords);

    //Memory allocation for noOfRecords structures
    ptr = (struct course *)malloc(noOfRecords * sizeof(struct course));
    ptr->subject=(char*)malloc(20*sizeof(char));

    for (i = 0; i < noOfRecords; ++i) {
        printf("Enter the name of the subject and marks respectively:\n");
        scanf("%s %d", (ptr + i)->subject, &(ptr + i)->marks);
    }

    printf("Displaying Information:\n");
    for (i = 0; i < noOfRecords; ++i){
       printf("%s\t%d\n", (ptr + i)->subject, (ptr + i)->marks);

    }
      return 0;
}

【问题讨论】:

  • ptr-&gt;subject=(char*)malloc(20*sizeof(char)); 只为数组中的 first struct 元素的成员分配内存。您需要在循环内为每个元素执行此操作。
  • OT: about: int main(int argc, char *argv[]) 由于没有使用这些参数,编译器会输出两条关于未使用参数的警告消息。这可以通过使用 main() int main( void ) 的备用有效签名或 main 正文中的前几个语句来解决:(void)argc;(void)argv;
  • OT:关于ptr = (struct course *)malloc(noOfRecords * sizeof(struct course));ptr-&gt;subject=(char*)malloc(20*sizeof(char)); 1) 返回的类型是void*,可以分配给任何指针。强制转换只会使代码混乱(并且容易出错)2)始终检查(!= NULL)返回值以确保操作成功。如果不成功(==NULL),则调用perror( "malloc for ... failed" ) to output to stderr`你的错误消息和系统认为错误发生的文本原因
  • OT:关于:scanf("%d", &amp;noOfRecords); 在调用任何scanf() 系列函数时,始终检查返回值(而不是参数值)以确保操作成功。注意:这些函数返回成功的“输入格式转换说明符”(或 EOF)的数量。建议:if( scanf("%d", &amp;noOfRecords) != 1 ) { fprintf( stderr, "scanf for number of records failed\n" );目前代码逻辑无法恢复,所以下一条语句应该是:exit( EXIT_FAILURE );
  • @MariaXentoulis 你应该选择一个正确的答案......

标签: c


【解决方案1】:

如问题 cmets 所述,您需要为所有subject 成员分配内存,而不仅仅是第一个:

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

struct course {
    int marks;
    char *subject;
};

int main(int argc, char *argv[])
{
    struct course *ptr;
    int i, noOfRecords;

    printf("Enter the number of records: "); 
    scanf("%d", &noOfRecords);

    //Memory allocation for noOfRecords structures
    ptr = (struct course *)malloc(noOfRecords * sizeof(struct course));

    for (i = 0; i < noOfRecords; ++i) {
        printf("Enter the name of the subject and marks respectively:\n");
        (ptr + i)->subject = (char*) malloc(20*sizeof(char));
        scanf("%s %d", (ptr + i)->subject, &((ptr + i)->marks));
    }

    printf("Displaying Information:\n");
    for (i = 0; i < noOfRecords; ++i) {
       printf("%s\t%d\n", (ptr + i)->subject, (ptr + i)->marks);
    }

    return 0;
}

另外,我建议你:

  • 使用#define 作为主题最大长度
  • 始终检查用户输入或对其进行限制(截断或强制重新输入)。如果用户插入超过 19 个字符加上 \0 作为主题,您可能会遇到意外行为。
  • 使用typedef struct {...} course;。处理数组会容易得多。
  • 记得释放你申请的内存。

结果:

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

// From https://stackoverflow.com/a/17387990/2928168
#define MAX_SUBJECT "20"

typedef struct {
    int marks;
    char *subject;
} Course;

int main(int argc, char *argv[])
{
    Course *courses;
    int i, noOfRecords;

    printf("Enter the number of records: "); 
    scanf("%d", &noOfRecords);

    // Memory allocation for noOfRecords structures
    courses = (Course *) malloc(noOfRecords * sizeof(Course));

    for (i = 0; i < noOfRecords; ++i) {
        printf("Enter the name of the subject and marks respectively:\n");
        courses[i].subject = (char*) malloc(atoi(MAX_SUBJECT)*sizeof(char));
        scanf("%" MAX_SUBJECT "s %d", courses[i].subject, &(courses[i].marks));
        //fgets(courses[i].subject, sizeof(buf), stdin);
    }

    printf("Displaying Information:\n");
    for (i = 0; i < noOfRecords; ++i) {
       printf("%s\t%d\n", courses[i].subject, courses[i].marks);
       free(courses[i].subject);
    }

    free(courses);

    return 0;
}

编辑

您甚至可以使用 https://stackoverflow.com/a/6671729/2928168 的技巧来提高性能:

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

#define MAX_SUBJECT 20
#define Q(x) #x
#define QUOTE(x) Q(x)
#define MAX_SUBJECT_STR QUOTE(MAX_SUBJECT)

typedef struct {
    int marks;
    char *subject;
} Course;

int main(int argc, char *argv[])
{
    Course *courses;
    int i, noOfRecords;

    printf("Enter the number of records: "); 
    scanf("%d", &noOfRecords);

    // Memory allocation for noOfRecords structures
    courses = (Course *) malloc(noOfRecords * sizeof(Course));

    for (i = 0; i < noOfRecords; ++i) {
        printf("Enter the name of the subject and marks respectively:\n");
        courses[i].subject = (char*) malloc(MAX_SUBJECT*sizeof(char));
        scanf("%" MAX_SUBJECT_STR "s %d", courses[i].subject, &(courses[i].marks));
        //fgets(courses[i].subject, sizeof(buf), stdin);
    }

    printf("Displaying Information:\n");
    for (i = 0; i < noOfRecords; ++i) {
       printf("%s\t%d\n", courses[i].subject, courses[i].marks);
       free(courses[i].subject);
    }

    free(courses);

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-07
    • 2011-03-18
    • 2021-06-14
    • 2021-05-04
    • 2021-06-30
    相关资源
    最近更新 更多