Ich arbeite derzeit an dem Erstellen eines kleinen Compilers, der C++ verwendet. Ich habe die folgenden Objekte definiert:Segmentierungsfehler beim Zugriff auf den Speicherort nach dem Zuweisen von Speicher mit malloc()
struct ValueNode
{
std::string name;
int value;
};
struct StatementNode
{
StatementType type;
union
{
struct AssignmentStatement * assign_stmt;
struct PrintStatement * print_stmt;
struct IfStatement * if_stmt;
struct GotoStatement * goto_stmt;
};
struct StatementNode * next; // next statement in the list or NULL
};
Ich habe eine Reihe von Funktionen definiert, die sich auf verschiedene Arten von Anweisungen in der Sprache beziehen. Eine dieser Funktionen heißt parse_assignment_stmt(). Der Segmentierungsfehler, den ich erfahre, tritt in dieser Funktion unmittelbar nach dem Versuch auf, dem kürzlich zugewiesenen Speicher einen Wert zuzuweisen. Hier ist die Funktion:
struct StatementNode* parse_assign_stmt() {
//Object to be returned. Holds an object representing a statement
//made within the input program.
struct StatementNode* st = (struct StatementNode*)malloc(sizeof(struct StatementNode));
st->type = ASSIGN_STMT;
//First token should be an ID. Represents memory location we are assigning to.
Token tok = lexer->GetToken();
if(tok.token_type == ID) {
//Second token in an assignment should be an equal sign
Token tok2 = lexer->GetToken();
if (tok2.token_type == EQUAL) {
//This function reads the next token, makes sure it is of type NUM or ID, then creates and returns a ValueNode containing the relevant value.
struct ValueNode* rhs1 = parse_primary();
Token tok3 = lexer->GetToken();
//Assignment format for this logical branch: "x = 5;"
if(tok3.token_type == SEMICOLON) {
//first type
//Allocate memory for objects needed to build StatementNode st
struct AssignmentStatement* assign_stmt = (struct AssignmentStatement*)malloc(sizeof(struct AssignmentStatement));
struct ValueNode* lhs = (struct ValueNode*)malloc(sizeof(struct ValueNode));
printf("Name: %s, Value: %d\n", lhs->name.c_str(), lhs->value);
//PROBLEM ARISES HERE***
//lhs->name = tok.lexeme;
//return the proper structure
return st;
}
else if(tok3.token_type == PLUS || tok3.token_type == MINUS || tok3.token_type == DIV || tok3.token_type == MULT) {
//second type
//TODO
}
else {
printf("Syntax error. Semicolon or operator expected after first primary on RHS of assignment.");
exit(1);
}
}
else {
//not of proper form
printf("Syntax error. EQUAL expected after LHS of assignment.");
exit(1);
}
}
else {
//Not of proper form. Syntax error
printf("Syntax error. ID expected at beginning of assignment.");
exit(1);
}
}
Im Wesentlichen bin ich Speicher für einen neuen ValueNode zuweisen, um die Variable lhs zu erstellen. Ich drucke die Felder Name und Wert sofort aus, um sicherzustellen, dass nichts vorhanden ist. In meiner Compiler-Ausgabe (ich verwende übrigens g ++), sagt es mir, dass der Name (null) ist und der Wert 0 ist, was erwartet wird. Sobald ich die Zeile auslasse
lhs->name = tok.lexeme;
bekomme ich einen Segmentierungsfehler. An diesem Punkt habe ich keine Ahnung, was schief gehen könnte. Ich erstelle die Variable, benutze malloc, um dem Ort Speicher zuzuweisen, stelle sicher, dass dort nichts gespeichert ist, und versuche dann sofort, einen Wert zu schreiben. Und es gibt mir immer einen Segmentierungsfehler.
Hier ist das Eingabeprogramm (.txt-Datei), das dem Programm über stdin zugeführt wird.
i;
{
i = 42 ;
print i;
}
ich versucht habe, mit calloc() statt, da das sollte darauf achten, dass der Speicher vor der Rückkehr in den Zeiger gelöscht wird, aber das hat nichts ändern. Irgendwelche Vorschläge wären wunderbar. Vielen Dank!
Verwenden Sie 'malloc()' nicht mit C++ - Code. – user0042
Sie sollten in Erwägung ziehen, Ihre unionierte 'Struktur' durch eine geeignete Vererbungshierarchie zu ersetzen. Dann werden Sie nicht als C + -Programmierer gedacht, diese seltsame Rasse, die nie ganz den Übergang voll von C nach C++ macht :-) – paxdiablo
[Diese Frage] (https://stackoverflow.com/questions/46991224/are- there-any-valid-use-cases-to-use-new-and-delete-raw-pointers-oder-c-style-arr) gibt Ihnen auch einige Hinweise, wie und warum man die manuelle Zuweisung von dynamischem Speicher für die meisten Fälle fallen lassen sollte in C++ vollständig. – user0042