C语言实现文件匹配记录升序打印时程序崩溃问题求助
Hey there! Let's dig into why your program keeps crashing and fix it step by step. From the code snippets you shared, there are a few key issues that are likely triggering the crash:
1. Uninitialized Pointer & Missing Memory Allocation
You declared char *records; but never allocated memory for it, nor did you set up an array (static or dynamic) to store the records you read. Accessing an uninitialized pointer like this leads to invalid memory access, which is a common cause of program crashes.
2. Incomplete File Reading Logic
Your fopen("con... is cut off, but it’s clear you’re not properly storing the records you read from the file. If you’re using a temporary stack buffer and just saving pointers to it, those pointers will become invalid once the buffer is overwritten or goes out of scope—causing qsort to access garbage memory during sorting.
3. Potential Invalid Pointers in Sorting
While your myCompare function looks correct for sorting an array of string pointers, it will crash if any pointer in the array points to invalid memory (like unallocated space or expired stack memory).
Here’s a fixed version of your code with proper memory management, file handling, and matching logic:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> // Comparison function for qsort (unchanged, works correctly for string arrays) static int myCompare(const void *a, const void *b) { return strcmp(*(const char **)a, *(const char **)b); } void sort(const char *arr[], int n) { qsort(arr, n, sizeof(const char *), myCompare); } void search_contact() { FILE *fp; bool found = false; const char **matched_records = NULL; // Dynamic array to store matching records int record_count = 0; char buffer[256]; // Temporary buffer for reading lines (adjust size as needed) char user_input[256]; // Assume we get user input here // Get user input (add your actual input logic here) printf("Enter search keyword: "); fgets(user_input, sizeof(user_input), stdin); user_input[strcspn(user_input, "\n")] = '\0'; // Remove newline // Open the file (replace with your actual filename) fp = fopen("contacts.txt", "r"); if (fp == NULL) { perror("Failed to open file"); return; } // Read each line from the file while (fgets(buffer, sizeof(buffer), fp) != NULL) { // Remove trailing newline character buffer[strcspn(buffer, "\n")] = '\0'; // Check if the line matches user input (adjust match logic as needed) if (strstr(buffer, user_input) != NULL) { // Allocate memory to store the matched record permanently char *record_copy = strdup(buffer); if (record_copy == NULL) { perror("Failed to allocate memory for record"); goto cleanup; // Clean up and exit if allocation fails } // Expand the dynamic array to hold the new record const char **temp = realloc(matched_records, sizeof(const char *) * (record_count + 1)); if (temp == NULL) { perror("Failed to expand record array"); free(record_copy); goto cleanup; } matched_records = temp; matched_records[record_count++] = record_copy; found = true; } } // Sort and print matched records if any if (found) { sort(matched_records, record_count); printf("\nMatching records (sorted):\n"); for (int i = 0; i < record_count; i++) { printf("- %s\n", matched_records[i]); } } else { printf("\nNo matching records found.\n"); } cleanup: // Free all allocated memory to avoid leaks for (int i = 0; i < record_count; i++) { free((void *)matched_records[i]); } free(matched_records); fclose(fp); }
Key Fixes & Improvements:
- Dynamic Memory Allocation: Uses
strdupto save permanent copies of matched records, andreallocto expand the record array as needed. - Error Handling: Adds checks for file opening failures and memory allocation errors, with proper cleanup to avoid leaks.
- Valid Pointers: All pointers passed to
qsortpoint to valid, persistent memory, so sorting won’t crash. - Memory Cleanup: Frees all allocated memory and closes the file before exiting the function.
内容的提问来源于stack exchange,提问作者qwerty12345

