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

使用malloc创建指针数组出现段错误求助:最长字符串查找程序问题

排查指向指针数组指针的段错误问题

嘿,我明白你在摆弄指向指针数组的指针时有多头疼——段错误这种没太多提示的问题确实磨人。先看看你代码里的几个核心问题,这些就是导致崩溃的根源:

核心问题分析

  • 野指针未初始化:你声明了char **array并给它分配了存放n个char指针的空间,但每个char指针本身还没指向有效的内存,直接往这些野指针里写字符串肯定会触发段错误。
  • 未给长度数组分配内存:int *L也是个野指针,你打算用它存每个字符串的长度,但没给它分配内存,访问L[i]的时候会非法访问内存。
  • 输入缓冲区残留换行:用scanf("%d", &n)之后,输入框里的换行符会留在缓冲区,后续读字符串时可能会读到空内容,间接引发问题。

修正后的完整代码

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

int main() {
    char **array;
    int i, n, *L, maxlen, maxIndex = 0;
    char buffer[1024]; // 临时缓冲区,或者用getline更灵活

    printf("Enter the number of strings that you wish to store : ");
    // 检查scanf是否成功,避免无效输入
    if (scanf("%d", &n) != 1 || n <= 0) {
        printf("Invalid input for number of strings!\n");
        return 1;
    }
    // 吃掉scanf留下的换行符
    getchar();

    // 分配存放n个char指针的数组空间
    array = malloc(n * sizeof(char*));
    if (!array) {
        perror("malloc failed for array");
        return 1;
    }
    // 分配存放长度的数组空间
    L = malloc(n * sizeof(int));
    if (!L) {
        perror("malloc failed for length array");
        free(array); // 避免内存泄漏
        return 1;
    }

    // 读取每个字符串
    for (i = 0; i < n; i++) {
        printf("Enter string %d: ", i+1);
        // 用fgets读,避免缓冲区溢出,同时处理换行
        if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
            printf("Failed to read string!\n");
            // 清理已分配的内存
            for (int j = 0; j < i; j++) free(array[j]);
            free(array);
            free(L);
            return 1;
        }
        // 去掉fgets读入的换行符
        buffer[strcspn(buffer, "\n")] = '\0';
        // 给当前字符串分配刚好足够的内存
        array[i] = malloc(strlen(buffer) + 1);
        if (!array[i]) {
            perror("malloc failed for string");
            // 清理已分配的内存
            for (int j = 0; j < i; j++) free(array[j]);
            free(array);
            free(L);
            return 1;
        }
        strcpy(array[i], buffer);
        // 记录长度
        L[i] = strlen(array[i]);
    }

    // 找最长字符串
    maxlen = L[0];
    for (i = 1; i < n; i++) {
        if (L[i] > maxlen) {
            maxlen = L[i];
            maxIndex = i;
        }
    }

    printf("\nLongest string is: %s\nLength: %d\n", array[maxIndex], maxlen);

    // 释放所有分配的内存
    for (i = 0; i < n; i++) {
        free(array[i]);
    }
    free(array);
    free(L);

    return 0;
}

关键修改点说明

  • 给array的每个元素单独分配内存,确保每个字符串都有合法的存储空间
  • 给L分配了n个int大小的内存,用来安全存储每个字符串的长度
  • 用getchar()处理了scanf后的换行符,避免影响后续字符串读取
  • 加入了内存分配失败的检查,避免程序在内存不足时崩溃
  • 最后彻底释放所有动态分配的内存,避免内存泄漏
  • 用fgets代替scanf("%s"),避免缓冲区溢出的问题

下次遇到段错误,可以先检查所有指针是否都指向了合法的内存空间——野指针和越界访问是C语言段错误的头号元凶哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:29:46