分段错误,以及如何使用联合类型

时间:2016-07-04 19:15:40

标签: c debugging makefile segmentation-fault unions

我在C中构建一个顶点库,由于某种原因我得到了一个分段错误。我将首先展示代码并提出问题:

Vertex.h:

#ifndef _VERTEX_AM_H_LB
#define _VERTEX_AM_H_LB 1
#pragma once
#include<stdint.h>
/**
 * Vertex Library C
 *
 * GCC C99 <Vertex.h>
 *
 * @author Amanuel Bogale
 * @copyright 2016 Amanuel Bogale
 * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
 *
 */

//@union for storing
//data types supported
//for vertex
typedef union
    {
        char ch; //1 byte
        unsigned char uch;//1 byte
        signed char sch;// 1 byte
        int in;//2 or 4bytes
        unsigned int uin;//2 or 4bytes
        long ln;// 4byte
        unsigned long uln; //4byte
        long long lnln; //8byte
        short sh;// 2byte
        unsigned short ush; //2bytes
        float fl;//4byte
        double db; //8byte
        long double ldb; //10byte
}type;

/*
 * @struct for defining
 * vertex. Initalize First
 */
struct vertex_am
{
    size_t current_size;
    type type;
    long long size_contents;
    void **contents; //Array Of Void Pointers
    //Add to the end of array
    void (*add)(struct vertex_am *self,void*val);
};

typedef struct vertex_am vertex_am;



vertex_am* init_vertex(size_t size, vertex_am* vertex);
void end_vertex(vertex_am* vertex);
long long get_elements_num(vertex_am vert);
void add_end(vertex_am vert, void* val);
void* get_val(vertex_am vert,long long index);
#endif

Vertex.c:

#include<stdlib.h>
#include<stdio.h>
#include "../includes/Vertex.h"

/**
 * Vertex Library C
 *
 * GCC C99 <Vertex.c>
 *
 * @author Amanuel Bogale
 * @copyright 2016 Amanuel Bogale
 * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
 *
 */

vertex_am* init_vertex(size_t size, vertex_am* vertex)
{
    vertex = malloc(size);
    vertex->current_size = size;
    vertex->size_contents = 0;
    return vertex;
}

long long get_elements_num(vertex_am vert)
{
    return(vert.size_contents);
}

void add_end(vertex_am vert, void* val)
{
    vert.contents[vert.size_contents] = val;
    vert.size_contents++;
}

void* get_val(vertex_am vert,long long index)
{
    return (vert.contents[index]);
}


void end_vertex(vertex_am* vertex)
{
    free(vertex);
}

main.c中:

#include<stdlib.h>
#include<stdio.h>
#include<stdint.h>
#include "includes/Vertex.h"

int main()
{
    printf("In");
    vertex_am *vert = NULL;
    vert = init_vertex(sizeof(*vert), vert);
    add_end(*vert,(void *)34);
//  printf ("%d", *((int*)get_val(*vert, 0) ));
    end_vertex(vert);
    return 0;
}

生成文件:

C = gcc 
TARGETS = main 
SUB_TARGETS = sources/Vertex.c
CFLAGS = -Wall -g -std=c99  -pthread  -Werror -o exec -g -Q -O0


all: clean $(TARGETS)

$(TARGETS):
    $(C) $(CFLAGS) $@.c $(SUB_TARGETS) -o $@

clean:
    rm -f $(TARGETS)

好的我有几个问题。

  1. 我上面有一个分段错误。我无法找到它的位置。请帮助
  2. gcc和linux环境的任何分段错误调试器
  3. 我如何使用工会来修复类型。我的意思是像vector_am vec。我怎么去,所以我得到用户想要的类型使用联盟。或者虚空*已经是一个更好的主意了吗?
  4. 帮助将不胜感激。谢谢你的阅读。

2 个答案:

答案 0 :(得分:2)

  

我上面有一个分段错误。我无法找到它的位置

使用gdb执行代码

gdb ./exec
然后键入&#39;运行&#39;并且gdb会发挥他的魔力,并告诉你分段错误的确切位置,你将能够理解为什么。

从阅读代码看起来你正在访问vert.contents指针而没有为它分配内存......

vert.contents[vert.size_contents]

vert.contents是一个没有分配/初始化的双指针

  

gcc和linux环境的任何分段错误调试器

到目前为止,gdb是我所知道的最好的......

答案 1 :(得分:1)

您可以通过执行以下操作找到分段故障位置:

  • 使用gcc -g编译以添加调试信息
  • 使用gdb ./yourprogram
  • 运行您的程序
  • 在GDB提示符下,按r以运行程序
  • 当它崩溃时,请写bt以获得回溯。

对于崩溃本身,看起来您没有为vertex_am's contents成员分配内存,因此访问它会导致崩溃。