我在这里说的真的不多。 这是我的词法分析器文件:
#include <ctype.h>
#include <stdio.h>
#include "vector.h"
enum TokenType
{
tok_let = -1,
tok_iden = -2,
tok_int = -3,
tok_end = -4
};
typedef struct
{
int type;
char* str_d;
int int_d;
} Token;
char* seed;
int i=0;
char next_char()
{
i++;
return seed[i-1];
}
vector* get_tokens(char* in)
{
vector *toks;
vector_new(toks);
seed = in;
char tap;
if(isalpha(tap = next_char()))
{
char* iden_str="";
iden_str += tap;
char nc;
while(isalnum((nc = next_char())))
iden_str += nc;
if(iden_str == "let")
{
Token* tp;
tp->type = tok_let;
vector_push(toks, (void*)tp);
goto out;
}
Token* tp;
tp->type = tok_iden;
tp->str_d = iden_str;
vector_push(toks, (void*)tp);
}
out:
return toks;
}
int main()
{
vector* toks;
toks = get_tokens("let");
Token* ftok = (Token*)vector_get(toks, 0);
switch(ftok->type)
{
case tok_let:
printf("Its a let\n");
break;
default:
printf("Ummm lol nup\n");
break;
}
}
这是我的矢量文件:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct d_vector
{
void **items;
int capacity;
int total;
} vector;
void vector_new(vector *v)
{
v->capacity = 4;
v->total = 0;
v->items = malloc(sizeof(void*)*v->capacity);
}
int vector_total(vector *v)
{
return v->total;
}
static void vector_resize(vector *v, int capacity)
{
void** items = realloc(v->items, sizeof(void*) * capacity);
if(items)
{
v->items = items;
v->capacity = capacity;
}
}
void vector_push(vector *v, void* item)
{
if(v->capacity == v->total)
vector_resize(v, v->capacity * 2);
v->items[v->total++] = item;
}
void vector_set(vector *v, int index, void* item)
{
if(index >= 0 && index < v->total)
v->items[index] = item;
}
void* vector_get(vector *v, int index)
{
if(index >= 0 && index < v->total)
return v->items[index];
return NULL;
}
void vector_remove(vector *v, int index)
{
if(index < 0 || index >= v->total)
return;
v->items[index] = NULL;
for (int i = 0; i < v->total - 1; i++) {
v->items[i] = v->items[i + 1];
v->items[i + 1] = NULL;
}
v->total--;
if (v->total > 0 && v->total == v->capacity / 4)
vector_resize(v, v->capacity / 2);
}
void vector_free(vector *v)
{
free(v->items);
}
当我运行上面的代码时,我得到了一个Seg-Fault。 怎么会发生这种情况?这是gdb的输出:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400656 in vector_new (v=0x1) at vector.h:14
14 v->capacity = 4;
正如你所看到的那样,当我设置矢量容量时它会分裂! 但为什么呢?
答案 0 :(得分:1)
因为您取消引用垃圾指针而导致段错误:
vector* get_tokens(char* in)
{
vector *toks;
vector_new(toks);
变量toks
没有分配给任何有意义的东西,只是垃圾值碰巧浮出水面。这会被传递到vector_new()
,立即取消引用它:
void vector_new(vector *v)
{
v->capacity = 4;
然后是BAM!它会爆炸,因为v
点不合适。
在致电malloc
之前尝试vector
vector_new()
或将malloc
放入vector_new()
并让指针返回新vector
{1}}而是。从malloc()
检查返回值也是个好主意。
您可以尝试以下方式:
vector *vector_new(void)
{
vector *v;
if ( (v = malloc(sizeof(*v))) == NULL ) {
/* Replace with something appropriate */
exit(EXIT_FAILURE);
}
v->capacity = 4;
v->total = 0;
if ( (v->items = malloc(sizeof(*v->items)*v->capacity)) == NULL ) {
/* Replace with something appropriate */
exit(EXIT_FAILURE);
}
return v;
}
然后改变你的称呼方式:
vector* get_tokens(char* in)
{
vector *toks;
toks = vector_new();
对于每个malloc()
,请设free()
。不要忘记清理这个分配,否则你会泄漏内存:
void vector_free(vector *v)
{
free(v->items);
free(v);
}
(您定义了一个vector_free()
,但从未调用它。您可能也想考虑这样做。)
答案 1 :(得分:1)
无效指针解除引用
vector *toks;
vector_new(toks);
应该是
vector *toks = (vector*)malloc(sizeof(vector));
vector_new(toks);