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 */
根本不需要。