我正在尝试从文件中查找按字母顺序排列的第一行的位置。读取每一行并将其存储在数组中时,出现分段错误。这是代码,

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define BUFSIZE 1024

int read_lines(char *filename, char ***array, int size) {
    char buf_file[BUFSIZE], buf_line[16];
    FILE *fp = fopen(filename,"r");
    if (fp == NULL) {
        return -1;
    }else{
        while (fgets(buf_file, BUFSIZE, fp))
            if (!(strlen(buf_file) == BUFSIZE-1 && buf_file[BUFSIZE-2] != '\n'))
                size++;
        array = malloc(size * sizeof(char*));
        rewind(fp);
        size = 0;
        while (!feof(fp)) {
            fscanf(fp, "%s", buf_line);
            strcpy(*array[size], buf_line);
            size++;
        }
        *array[size] = NULL;
    }
    fclose(fp);
    return size;
}

int shortest_string (char **array, int len)
{
    int i = 0;
    int smallestElement = -1;
    int smallestElementLength = 0;
    if(len == 0){
        return -1;
    }
    for(;i < len; i++){
        int elen = strlen(array[i]);
        if(elen < smallestElementLength){
            smallestElementLength = elen;
            smallestElement = i;
        }
    }
    return smallestElement;
}

int find_lexi_first (char **array, int len)
{
    char t[BUFSIZE];
    int i = 1, j =1, where = -1;
    if(len == 0){
        return -1;
    }
    for (; i < len; i++) {
      for (; j < 5; j++) {
         if (strcmp(array[j - 1], array[j]) > 0) {
            where = j;
            strcpy(t, array[j - 1]);
            strcpy(array[j - 1], array[j]);
            strcpy(array[j], t);
         }
      }
   }
    return where;
}

int main() {
    char* filename = "textfile.txt";
    char **array=NULL;
    int size = 0;

    int len = read_lines(filename, &array, size);
    printf("Read %d lines from file %s\n", len, filename);

    int  index = shortest_string (array, len);
    printf("Shortest line in row %d is: %s\n", index+1, array[index]);

    index = find_lexi_first (array, len);
    printf("Lexicographically first row in pos %d is: %s\n", index+1, array[index]);
    return 0;
}


这是细分错误,

    ==5910== Memcheck, a memory error detector
==5910== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5910== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5910== Command: ./out
==5910==
==5910== Use of uninitialised value of size 4
==5910==    at 0x804878B: read_lines (main.c:24)
==5910==    by 0x8048A30: main (main.c:77)
==5910==
==5910== Invalid read of size 4
==5910==    at 0x804878B: read_lines (main.c:24)
==5910==    by 0x8048A30: main (main.c:77)
==5910==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==5910==
==5910==
==5910== Process terminating with default action of signal 11 (SIGSEGV)
==5910==  Access not within mapped region at address 0x0
==5910==    at 0x804878B: read_lines (main.c:24)
==5910==    by 0x8048A30: main (main.c:77)
==5910==  If you believe this happened as a result of a stack
==5910==  overflow in your program's main thread (unlikely but
==5910==  possible), you can try to increase the size of the
==5910==  main thread stack using the --main-stacksize= flag.
==5910==  The main thread stack size used in this run was 8388608.
==5910==
==5910== HEAP SUMMARY:
==5910==     in use at exit: 400 bytes in 2 blocks
==5910==   total heap usage: 2 allocs, 0 frees, 400 bytes allocated
==5910==
==5910== LEAK SUMMARY:
==5910==    definitely lost: 0 bytes in 0 blocks
==5910==    indirectly lost: 0 bytes in 0 blocks
==5910==      possibly lost: 0 bytes in 0 blocks
==5910==    still reachable: 400 bytes in 2 blocks
==5910==         suppressed: 0 bytes in 0 blocks
==5910== Rerun with --leak-check=full to see details of leaked memory
==5910==
==5910== For counts of detected and suppressed errors, rerun with: -v
==5910== Use --track-origins=yes to see where uninitialised values come from
==5910== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)


为了动态分配内存,我尝试从文件中计算行号,然后使用malloc为每一行分配内存。我无法调试代码。快速说明:我刚刚在textfile.txt中输入了随机文本,我试图用红色表示代码。

最佳答案

在strcpy中,目标位于未初始化的内存中。
您必须为从文件中读取的每个字符串执行malloc。

我修改了read_lines却没有做太多改变:

int read_lines(char *filename, char ***array, int size) {
    char buf_file[BUFSIZE], buf_line[16];
    FILE *fp = fopen(filename,"r");
    char ** strings;

    if (fp == NULL) {
        return -1;
    }else{
        while (fgets(buf_file, BUFSIZE, fp))
            if (!(strlen(buf_file) == BUFSIZE-1 && buf_file[BUFSIZE-2] != '\n'))
                size++;
        strings = malloc(size * sizeof(char*));
        *array = strings;
        rewind(fp);
        size = 0;
        while (!feof(fp)) {
            fscanf(fp, "%s", buf_line);
            strings[size] = strdup(buf_line);
            size++;
        }
    }
    fclose(fp);
    return size - 1;
}


我正在使用strdup执行分配和复制。
我也相信您打算返回size-1,因为这是实际复制的字符串数。

10-07 12:29