C编程语言中的指针数组(第5.6章)示例

我的理解是,一旦指针初始化为字符串常量,就不能修改字符串。 我尝试过执行修改,程序崩溃了。

该理论在Brian W. Kernighan和Dennis M. Ritchie的C编程语言的第5.5章“字符指针和函数”中给出。

但是,有一个在数组中存储指针的例子(第5.6章),其中指针的内容被修改。 该计划如下:

#include  #include  #define MAXLINES 5000 /* max #lines to be sorted */ #define MAXLEN 1000 char *lineptr[MAXLINES]; /* pointers to text lines */ char *alloc(int); int readlines(char *lineptr[], int nlines); int getline(char *, int); void writelines(char *lineptr[], int nlines); main() { int nlines; /* number of input lines read */ if ((nlines = readlines(lineptr, MAXLINES)) >= 0) { writelines(lineptr, nlines); return 0; } else { printf("error: input too big to sort\n"); return 1; } } /* readlines: read input lines */ int readlines(char *lineptr[], int maxlines) { int len, nlines; char *p, line[MAXLEN]; nlines = 0; while ((len = getline(line, MAXLEN)) > 0) if (nlines >= maxlines) return -1; else { line[len-1] = '\0'; /* delete newline */ strcpy(p, line); lineptr[nlines++] = p; } return nlines; } /* writelines: write output lines */ void writelines(char *lineptr[], int nlines) { int i; for (i = 0; i < nlines; i++) printf("%s\n", lineptr[i]); } int getline(char s[],int lim) { int c, i; for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) s[i] = c; if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i; } 

编译时程序不显示任何警告或错误,但在输入第一行后崩溃。

你能否确认这是否是由于修改了一个初始化为指针的字符串常量? 有问题的指针是@ line 28“char * p”,并在它上面执行了strcpy @ 35行。谢谢。

它在这里崩溃了

  strcpy(p, line); 

因为p不指向分配的内存; 你应该添加这样的东西

 p = (char*)malloc(sizeof(char)* MAXLEN); 

更新:

也在这里

 for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) 

如果长度为MAXLEN的字符串以'\ n'结尾,则表示i可以达到lim值。 然后

 if (c == '\n') { s[i] = c; ++i; } 

你将'\ n'分配给s [MAXLEN](lim = MAXLEN),你将超越界限。 (索引应介于0和MAXLEN - 1之间MAXLEN - 1

我建议改变

 for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) 

 for (i=0; i < lim-2 && (c=getchar())!=EOF && c!='\n'; ++i) 

指针指向CAN的存储器的内容被修改
(否则它首先是没用的)。
你的意思是什么样的

 char *p = "hello"; 

这是一个特殊情况,你不允许你修改你好,但是……

你的问题:你没有指针的内容,即。 没有指定的记忆。
阅读malloc和免费。

你正在写一个unititialized指针。

你的声明

 char *p, line[MAXLEN]; 

然后你做

 strcpy(p, line); // here p points to invalid memory and therefore the program crashes 

你应该为p分配内存,如下所示

 else { line[len-1] = '\0'; /* delete newline */ p = (char*)malloc(len) ; // <<<<<<<<<<-- add this line strcpy(p, line); lineptr[nlines++] = p; 

BTW:一个没有警告编译的程序确实意味着它不会崩溃。 使用警告编译的程序可以完美运行。

您遇到的问题是readlines()中的char *p未定义。 正如您在当前的代码示例中所写的那样, p是一些随机内存块开头的地址,它是单个char的大小。 在K&R(第二版)示例代码中, readlines()while循环实际上如下所示:

 while((len = getline(line, MAXLEN)) > 0) { if (nlines >= maxlines || (p = alloc(len)) == NULL){ return -1; } else { line[len-1] = '\0'; strcpy(p, line); //now this should work lineptr[nlines++] = p; } } 

通过使用作者在第5章中已经定义的alloc()或者使用在定义的更合理的malloc() ,您可以将p定义为既有意义又安全的东西。使用/操作。

我知道这是一个挖掘,它可能无法解决您的问题,但这里的示例中有一个错误:

  line[len - 1] = '\0'; /* delete newline */ 

在代码之后的最后,它指向你在第1.9章中的getline() ,其中包含以下内容

 for(...; ... s[i] != '\n'; ...) s[i] = '\0'; 

getline()s[i] = '\0'来处理换行符,所以line[len - 1] = '\0'; /* delete newline */ line[len - 1] = '\0'; /* delete newline */根本不需要。