设置指针值时出现seg-fault

时间:2016-02-22 06:26:37

标签: c pointers memory segmentation-fault

我在这里说的真的不多。 这是我的词法分析器文件:

#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;

正如你所看到的那样,当我设置矢量容量时它会分裂! 但为什么呢?

2 个答案:

答案 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);