[英]Cpp: Segmentation fault core dumped
I am trying to write a lexer, when I try to copy isdigit buffer value in an array of char, I get this core dumped error although I have done the same thing with identifier without getting error.我正在尝试编写一个词法分析器,当我尝试将 isdigit 缓冲区值复制到一个 char 数组中时,我得到了这个核心转储错误,尽管我对标识符做了同样的事情而没有出错。
#include<fstream>
#include<iostream>
#include<cctype>
#include <cstring>
#include<typeinfo>
using namespace std;
int isKeyword(char buffer[]){
char keywords[22][10] = {"break","case","char","const","continue","default", "switch",
"do","double","else","float","for","if","int","long","return","short",
"sizeof","struct","void","while","main"};
int i, flag = 0;
for(i = 0; i < 22; ++i){
if(strcmp(keywords[i], buffer) == 0)
{
flag = 1;
break;
}
}
return flag;
}
int isSymbol_Punct(char word)
{
int flag = 0;
char symbols_punct[] = {'<','>','!','+','-','*','/','%','=',';','(',')','{', '}','.'};
for(int x= 0; x< 15; ++x)
{
if(word==symbols_punct[x])
{
flag = 1;
break;
}
}
return flag;
}
int main()
{
char buffer[15],buffer1[15];
char identifier[30][10];
char number[30][10];
memset(&identifier[0], '\0', sizeof(identifier));
memset(&number[0], '\0', sizeof(number));
char word;
ifstream fin("program.txt");
if(!fin.is_open())
{
cout<<"Error while opening the file"<<endl;
}
int i,k,j,l=0;
while (!fin.eof())
{
word = fin.get();
if(isSymbol_Punct(word)==1)
{
cout<<"<"<<word<<", Symbol/Punctuation>"<<endl;
}
if(isalpha(word))
{
buffer[j++] = word;
// cout<<"buffer: "<<buffer<<endl;
}
else if((word == ' ' || word == '\n' || isSymbol_Punct(word)==1) && (j != 0))
{
buffer[j] = '\0';
j = 0;
if(isKeyword(buffer) == 1)
cout<<"<"<<buffer<<", keyword>"<<endl;
else
{
cout<<"<"<<buffer<<", identifier>"<<endl;
strcpy(identifier[i],buffer);
i++;
}
}
else if(isdigit(word))
{
buffer1[l++] = word;
cout<<"buffer: "<<buffer1<<endl;
}
else if((word == ' ' || word == '\n' || isSymbol_Punct(word)==1) && (l != 0))
{
buffer1[l] = '\0';
l = 0;
cout<<"<"<<buffer1<<", number>"<<endl;
// cout << "Type is: "<<typeid(buffer1).name() << endl;
strcpy(number[k],buffer1);
k++;
}
}
cout<<"Identifier Table"<<endl;
int z=0;
while(strcmp(identifier[z],"\0")!=0)
{
cout <<z<<"\t\t"<< identifier[z]<<endl;
z++;
}
// cout<<"Number Table"<<endl;
// int y=0;
// while(strcmp(number[y],"\0")!=0)
// {
// cout <<y<<"\t\t"<< number[y]<<endl;
// y++;
// }
}
I am getting this error when I copy buffer1 in number[k] using strcpy.当我使用 strcpy 在 number[k] 中复制 buffer1 时出现此错误。 I do not understand why it is not being copied.
我不明白为什么它没有被复制。 When i printed the type of buffer1 to see if strcpy is not generating error, I got A_15, I searched for it, but did not find any relevant information.
当我打印 buffer1 的类型以查看 strcpy 是否没有产生错误时,我得到了 A_15,我搜索它,但没有找到任何相关信息。
The reason is here (line 56):原因在这里(第 56 行):
int i,k,j,l=0;
You might think that this initializes i
, j
, k
, and l
to 0
, but in fact it only initializes l
to 0
.您可能认为这会将
i
、 j
、 k
和l
初始化为0
,但实际上它只是将l
初始化为0
。 i
, j
, and k
are declared here, but not initialized to anything. i
, j
和k
在这里声明,但没有初始化为任何东西。 As a result, they contain random garbage, so if you use them as array indices you are likely to end up overshooting the bounds of the array in question.结果,它们包含随机垃圾,因此如果您将它们用作数组索引,您最终可能会超出相关数组的边界。
At that point, anything could happen—in other words, this is undefined behavior .到那时,任何事情都可能发生——换句话说,这是未定义的行为。 One likely outcome, which is probably happening to you, is that your program tries to access memory that hasn't been assigned to it by the operating system, at which point it crashes (a segmentation fault ).
一个可能发生在您身上的可能结果是,您的程序尝试访问尚未由操作系统分配给它的 memory,此时它崩溃(分段错误)。
To give a concrete demonstration of what I mean, consider the following program:为了具体说明我的意思,请考虑以下程序:
#include <iostream>
void print_var(std::string name, int v)
{
std::cout << name << ": " << v << "\n";
}
int main(void)
{
int i, j, k, l = 0;
print_var("i", i);
print_var("j", j);
print_var("k", k);
print_var("l", l);
return 0;
}
When I ran this, I got the following:当我运行它时,我得到以下信息:
i: 32765
j: -113535829
k: 21934
l: 0
As you can see, i
, j
, and k
all came out such that using them as indices into any of the arrays you declared would exceed their bounds.如您所见,
i
、 j
和k
都出现了,因此将它们用作您声明的任何 arrays 的索引将超出它们的范围。 Unless you are very lucky, this will happen to you, too.除非你很幸运,否则这也会发生在你身上。
You can fix this by initializing each variable separately:您可以通过分别初始化每个变量来解决此问题:
int i = 0;
int j = 0;
int k = 0;
int l = 0;
Initializing each on its own line makes the initializations easier to see, helping to prevent mistakes.在自己的行上初始化每个使初始化更容易看到,有助于防止错误。
A few side notes:一些旁注:
-Wall -Wextra
to your compiler or the like—check its documentation for the specifics).-Wall -Wextra
传递给您的编译器等 - 检查其文档以获取详细信息)。int
, they are signed integers, which means they can hold negative values (as j
did in my demonstration).int
,因此它们是有符号整数,这意味着它们可以保存负值(就像j
在我的演示中所做的那样)。 If you try to index into an array using a negative index, you will end up dereferencing a pointer to a location "behind" the start of the array in memory, so you will be in trouble even with an index of -1
(remember that a C-style array is basically just a pointer to the start of the array).-1
,您也会遇到麻烦(请记住C 风格的数组基本上只是指向数组开头的指针)。 Also, int
probably has only 32 bits in your environment, so if you're writing 64-bit code then it's possible to define arrays too large for an int
to fully cover, even if you were to index into the array from the middle.int
在您的环境中可能只有 32 位,因此如果您正在编写 64 位代码,则可以定义 arrays 太大而无法完全覆盖int
,即使您要从中间索引到数组。 For these sorts of reasons, it's generally a good idea to type raw array indices as std::size_t , which is always capable of representing the size of the largest possible array in your target environment, and also is unsigned.Some general hints that might help you to avoid your cause of crash totally by design:一些一般提示可能会帮助您完全通过设计避免崩溃原因:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.