我正在尝试从文件中查找按字母顺序排列的第一行的位置。读取每一行并将其存储在数组中时,出现分段错误。这是代码,
#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,因为这是实际复制的字符串数。