我正在尝试练习5.7。来自ANSI C书:
锻炼5.7。重写readlines将行存储在main提供的数组中,而不是调用alloc来维护存储。该程序快多少?
这是我的以下代码:
#include <stdio.h>
#include <string.h>
#define ALLOCSIZE 10000
#define MAXBUF 10000
#define MAXLEN 1000
#define MAXLINES 5000
char * lineptr[MAXLINES];
static char allocbuf[ALLOCSIZE];
static char * allocp = allocbuf;
int readlines(char * lineptr[], int nlines);
void writelines(char * lineptr[], int nlines);
int mygetline(char *, int);
void qsort(char * lineptr[], int left, int right);
void swap(char * v[], int i, int j);
int main(void) {
int nlines;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
qsort(lineptr, 0, nlines - 1);
writelines(lineptr, nlines);
} else {
printf("error: input too big to sort\n");
return 1;
}
return 0;
}
int readlines(char * lineptr[], int maxlines) {
int len, nlines;
char line[MAXLEN];
nlines = 0;
while ((len = mygetline(line, MAXLEN)) > 1) {
if (nlines >= maxlines || len == 0)
return -1;
else {
line[len - 1] = '\0';
strcpy(lineptr[nlines++], line);
}
}
return nlines;
}
void writelines(char * lineptr[], int nlines) {
while (nlines-- > 0)
printf("%s\n", *lineptr++);
}
int mygetline(char s[], int lim) {
int c, i;
i = 0;
while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
void qsort(char * v[], int left, int right) {
int i, last;
if (left >= right)
return;
swap(v, left, (left + right) / 2);
last = left;
for (i = left + 1; i <= right; i++)
if (strcmp(v[i], v[left]) < 0)
swap(v, ++last, i);
swap(v, left, last);
qsort(v, left, last);
qsort(v, last + 1, right);
}
void swap(char * v[], int i, int j) {
char * temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
我无法弄清楚这个练习。我在readlines
指令的strcpy(lineptr[nlines++], line);
函数中出错。我不知道为什么该指令会导致细分错误。谁能建议如何解决分段错误或提出另一种解决方案?
答案 0 :(得分:5)
char * lineptr[MAXLINES];
可以很好地声明一个指针数组,但是不初始化任何字符串。
所以做的时候
strcpy(lineptr[nlines++], line);
您正在使用未初始化的指针复制数据,从而导致随机存储位置导致... 未定义行为
相反,分配一些内存:
char *copy = malloc(strlen(line)+1);
strcpy(copy,line);
lineptr[nlines++] = copy;
或者只是
lineptr[nlines++] = strdup(line);
最后,您必须free
个。
一个不错的办法是检查nlines < MAXLINES