海湾合作委员会编译得很好,但只要scanf接受一个字符串它seg错误。我有点不知所措。这是代码。scanf导致seg故障?
char *line[256];
void *mainThread()
{
while (*line != "quit") {
scanf("%s", *line);
printf("%s", *line);
}
return;
}
有一些关于scanf函数我不理解这里?
海湾合作委员会编译得很好,但只要scanf接受一个字符串它seg错误。我有点不知所措。这是代码。scanf导致seg故障?
char *line[256];
void *mainThread()
{
while (*line != "quit") {
scanf("%s", *line);
printf("%s", *line);
}
return;
}
有一些关于scanf函数我不理解这里?
它正在编译,因为你的程序在语法上是正确的。然而,它具有严重的语义错误,由于段错误而导致程序崩溃。作为全局变量,全局数组line
被初始化为零。因为,line
是一个指针数组(不是指定的字符数组),因此零被解释为空指针NULL
。 *line
与line[0]
相同,字符串文字"quit"
的计算结果为指向其第一个元素的指针。因此,while
条件相同
while(NULL != "quit") // always true
接着,scanf("%s", *line);
试图通过line[0]
这是NULL
到输入字符串到缓冲器指针写入 - 这不等于任何存储器位置的地址的值。这将导致段错误并导致程序崩溃。
你的代码片段还有其他错误。让我们一个接一个。
char *line[256];
上述语句定义的阵列256的line
指针的字符,即,其
类型是char *[256]
。你需要的是一组字符 -
char line[256];
你不能比较阵列C
。你可以做的是逐个比较它们。对于字符串,您应该使用标准库函数strcmp
。另请注意,格式字符串scanf
中的%s
转换说明符从stdin
中读取一个字符串,并将其写入下一个参数指向的缓冲区。它在结尾处放置一个终止空字节,但如果输入的字符串太大而不能容纳缓冲区,则它不会检查缓冲区溢出。这会导致未定义的行为,并且由于非法内存访问,很可能导致段错误。您应该通过在格式字符串中指定最大字段宽度来防止缓冲区溢出。
void *mainThread();
上述函数声明意味着mainThread
是功能返回void *
类型的指针,并采取的参数未指定但固定数量和类型,因为空括号意味着没有关于参数列表信息被提供。您应该在参数列表中写入void
以表示该函数不带任何参数。还要注意,如果使用函数的返回值,则函数中的空return语句会导致未定义的行为,因为您没有返回任何内容,而是在函数的返回地址中使用垃圾值。假设你想返回字符串,它应该被定义为 -
char line[256];
char *mainThread(void) {
while(strcmp(line, "quit") != 0) {
scanf("%255s", line); // -1 for the terminating null byte
printf("%s", line);
}
return line;
}
首先,你分配的指针数组字符,而不是一个字符的数组:
char *line[256]; /* allocates 256 pointers to a character -
(pointers are initialized to NULL) */
您需要分配一个字符数组来代替:
char line[256]; /* allocates 256 characters */
其次,您需要使用strcmp
来比较字符串 - 与!=
,您正在比较存储在中的指针(地址)(与*line
相同),并带有一个指向字符串字面值"quit"
的指针,它们总是不同的。
您可以使用以下sscce为出发点:
#include <string.h>
#include <stdio.h>
char line[256];
int main()
{
while (strcmp(line, "quit") != 0) {
scanf("%s", line);
printf("%s", line);
}
return 0;
}
一些其他注意事项:
void*
,但你不返回任何东西(使用return
不带参数)。您应该简单地将其声明为void
。scanf()
读取输入,因为比你分配导致缓冲区溢出,可能更多的字符。改为使用fgets()
。另见Disadvantages of scanf。-Wall -pedantic
进行编译。你可能还想提一提,[这个程序处理较大的输入相当可怕](http://stackoverflow.com/q/1621394/274261)。 – ArjunShankar
谢谢! strcmp是一个明显的错误,愚蠢的我。我不想返回任何东西,这个函数返回一个void *指针,因为我使用pthreads。 – Ormannishe
在声明全局变量,它们被初始化为零。当你声明一个指向char
的指针数组(而不是我认为你真正打算的char
数组)时,你有一个256 NULL
指针数组。
阵列上的使用引用操作*
是一样的做得例如array[0]
,这意味着作为一个参数既scanf
和printf
要传递line[0]
,其如以上所解释的,是一个NULL
指针。取消引用指针NULL
,像scanf
和printf
会做,是未定义行为,一个几乎总是导致崩溃的情况。
你有没有分配任何内存'line [0] = malloc(...)'? –