gpt4 book ai didi

c - NULL 指针被随机修改为 0x62 或类似的

转载 作者:太空宇宙 更新时间:2023-11-04 08:43:48 25 4
gpt4 key购买 nike

我正在制作一个正则表达式解析器。指令“t->left = tmp;”指令“t->left = tmp;”造成段错误,但并非总是如此!尝试多次执行代码,您会发现它并不总是会发生。打印树时出现段错误,因为其中一个节点有一个地址为“0x62”或“0x54”或类似内容的子节点。这真的很奇怪,因为当创建“tmp”时,我检查两个 child 都是 NULL,但不知何故其中一个在执行时被修改为“0x..”。

感谢任何可以帮助我解决这个问题的人!

我花了很长时间试图弄清楚为什么在解析树时只添加一个“左 child ”会产生段错误。我真的不明白,因为这是一个简单的指针创建和赋值!注释指令“t->left = tmp;”段错误消失了!迄今为止最奇怪的问题..

最好的问候!

/*
* Includes
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
* Typedefs
*/

struct node {
char val;

struct node* left;
struct node* right;
};

typedef struct node NODE;
typedef struct node * TREE;

/*
* Tree handling
* - create
* - free
* - print
*/

TREE createNode(char val) {
TREE t = (TREE) malloc(sizeof(TREE));
t->val = val;
t->left = NULL;
t->right = NULL;

return t;
}

void freeTree(TREE t) {
if (t != NULL) {
if (t->left != NULL)
freeTree(t->left);
if (t->right != NULL)
freeTree(t->right);
free(t);
}
}

void printNode(TREE t) {
printf("------ NODE ------\n");
printf("t == %p\n", t);
if (t != NULL) {
printf("val = %c\n", t->val);
printf("left : %p\n", t->left);
printf("right : %p\n", t->right);
}
}

void printTree(TREE t) {
if (t != NULL) {
printf("%c\t[%p]\n", t->val, t);
printf("%p\n", t->left);
if (t->left != NULL) {
printf("----------------begin left----------------\n");
printTree(t->left);
printf("----------------end left----------------\n");
}
printf("%p\n", t->right);
if (t->right != NULL) {
printTree(t->right);
}
}
}

/*
* Misc functions
*/

char* concat(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator
//in real code you would check for errors in malloc here
strcpy(result, s1);
strcat(result, s2);
return result;
}

char* substr(char* s, int start) {
int i = 0;
char* sub = malloc(4*(strlen(s) - start) + 1); // +1 for the zero-terminator
while (s[i+start] != '\0') {
sub[i] = s[i+start];
i++;
}
return sub;
}

char* substr_(char* s, int start, int end) {
int i = 0;
char* sub = malloc(4*(strlen(s) - start) + 1); // +1 for the zero-terminator
while (s[i+start] != '\0' && i < (end-start+1)) {
sub[i] = s[i+start];
i++;
}
return sub;
}

/*
* Regex handling
*/

TREE parseParenthesis(char* regex) {

if (regex[0] == '\0') return NULL;

printf("%s\n",regex);

TREE tree = createNode(regex[0]);

int i = 0;
int start = 1;
int lastParenthesisPos = 0;;

switch (regex[0]) {
case '(' :
while (regex[i] != '\0') {
if (regex[i] == ')')
lastParenthesisPos = i;
i++;
}
tree->left = parseParenthesis(substr_(regex, 1, lastParenthesisPos-1));
start = lastParenthesisPos + 1;
break;
case '|' :
case ')' : // Handled by case ')'
case '*' :
case '+' :
case '?' :
default : break;
}

tree->right = parseParenthesis(substr(regex, start));

return tree;

}

void parseExtras(TREE t, TREE parent) {

if (t == NULL) return;

TREE tmp = NULL;

switch (t->val) {
case '*' :
case '+' :
case '?' :
parseExtras(t->right, t);
tmp = createNode(parent->val);
t->left = tmp;
break;
case '(' :
case ')' :
case '|' :
default :
parseExtras(t->left, t);
parseExtras(t->right, t);
break;
}

}

/*
* Main
*/

int main() {

//char* regex = "a|(b|c*)?d|ef";
char* regex = "ab*dd*";

// Parse ()
TREE t = parseParenthesis(regex);
printf("************************************ OK - Parse parenthesis\n");
// Parse * + ?
parseExtras(t, NULL);
printf("************************************ OK - Parse extras\n");

printTree(t);
printf("************************************ OK - Print tree\n");

freeTree(t);
printf("************************************ OK - Free tree\n");

return 0;

}

最佳答案

你只是为一个指针分配空间,而不是实际的结构:

    TREE t = (TREE) malloc(sizeof(TREE));

在此之后,您将修改超出 TREE(指针)大小的内存。

正如上面的评论所说,不要在不必要的情况下使用 typedef。

关于c - NULL 指针被随机修改为 0x62 或类似的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22464238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com