You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言结构体Library初始化后仅首元素可访问,其余触发Segmentation Fault

问题分析与修复

嘿,咱们来拆解下你遇到的段错误问题——核心原因是你对library结构体里的booklist数组的初始化逻辑完全错了,导致除第一个元素外,剩下的都是野指针,访问自然触发了内存权限错误。

问题到底出在哪?

你的lib结构体里,booklist是一个book*类型的数组(book* booklist[MAXBOOKS]),意思是数组里每个位置都要存放一个指向book对象的指针。但你初始化时写的{3,{list}},只是把malloc出来的book数组的首地址赋值给了booklist[0],booklist[1]和booklist[2]根本没被初始化,还是随机的垃圾值——也就是野指针。当printLibrary循环到i=1和i=2时,访问这些野指针指向的内存,直接就触发段错误了。

另外还有个隐藏坑:你的storeBook函数完全起不了作用,就算调用也会出问题——因为你传的是library的副本(值传递),函数里修改的只是副本的booklist,原结构体根本没变化;而且CurrentBook是函数的局部变量,函数结束后它的内存会被释放,你把它的地址存在booklist里,后续访问也是非法内存。

修复后的代码方案

咱们直接修正初始化逻辑,同时顺便把storeBook的坑也填上:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXBOOKS 10

typedef struct books {
    char* title;
    char* author;
    int id;
} book;

typedef struct library {
    int number_of_books;
    book* booklist[MAXBOOKS];
} lib;

// 修改为传指针,避免值传递的副本问题,同时传入合法的book指针
void storeBook(lib* library, book* CurrentBook) {
    // 先检查图书馆有没有空位
    if (library->number_of_books < MAXBOOKS) {
        library->booklist[library->number_of_books] = CurrentBook;
        library->number_of_books++;
    }
}

void printLibrary(lib library) {
    for(int i = 0; i < library.number_of_books; i++) {
        printf("Book %d:\nTitle: %s\nAuthor: %s\nID: %d\n\n", 
               i+1, library.booklist[i]->title, library.booklist[i]->author, library.booklist[i]->id);
    }
}

int main() {
    book b_1 = {"The trial","Kafka",101};
    book b_2 = {"The lurking fear","Lovecraft",102};
    book b_3 = {"Dora's storytime collection","Valdes",103};

    // 方法1:直接用栈上book对象的地址初始化booklist(最简单的方式)
    lib CurrentLibrary = {
        3, 
        {&b_1, &b_2, &b_3}  // 每个元素都指向对应的合法book对象
    };

    // 方法2:如果想用malloc的数组,需要循环给booklist每个元素赋值
    /*
    book* list = (book*)malloc(3*sizeof(book));
    list[0] = b_1;
    list[1] = b_2;
    list[2] = b_3;
    lib CurrentLibrary = {3, {}}; // 先初始化空数组
    for (int i=0; i<3; i++) {
        CurrentLibrary.booklist[i] = &list[i]; // 逐个指向malloc数组里的对应book
    }
    */

    printLibrary(CurrentLibrary);

    // 如果用了malloc,记得最后释放内存避免泄漏
    // free(list);

    return 0;
}

关键说明

  • booklist的正确初始化:要么直接把栈上b_1/b_2/b_3的地址逐个放进数组,要么用malloc数组时,循环把&list[i]赋值给booklist[i],确保每个元素都是合法指针。
  • 值传递的坑:修改结构体的函数一定要传指针,否则修改的只是副本,原对象不会有变化;同时绝对不要存储局部变量的地址,要传栈或堆上长期存在的对象指针。
  • 内存管理:如果用了malloc分配内存,记得最后用free释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Michael Bohanan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:26:33