-3

Im constructing A Vertex Library in C, and for some reason i get a Segmentation Fault. Im going to first show the code and ask question:

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

Makefile:

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)

Ok i have couple questions.

  1. I have a segmentation Fault above. And i cant locate where it is. Help Please
  2. Any Segmentation Fault Debugger for gcc and linux enviorment
  3. How would i go about using unions to manupliate types. By that i mean like this vector_am vec . How would i go so i get what the user wants as a type using union. Or is the void* already a better idea?

Help would be appreciated. Thanks for reading.

amanuel2
  • 4,508
  • 4
  • 36
  • 67
  • 2
    I have no idea what the code is supposed to do and I have no idea what you are asking in (3). – Eugene Sh. Jul 04 '16 at 19:18
  • I litterarly said its a Vertex Library. Meaning im making my own "class" for Dynamic Array. – amanuel2 Jul 04 '16 at 19:19
  • 1
    No one knows what "Vertex library" means to *you*. You should describe the behavior rather than asking from us to reverse-engineer your code. – Eugene Sh. Jul 04 '16 at 19:20
  • Im sure many people who do C has done atleast some C++, and there is a standard library in C++ For Vertex. What do you mean no one knows? You kiding me? There is also vertex in Java. C#. Do you want me to continue? – amanuel2 Jul 04 '16 at 19:22
  • 2
    I want you to bring the question to a format that fits SO. Right now it doesn't. – Eugene Sh. Jul 04 '16 at 19:24
  • type should have been enum, not union. The value itself could have been a union (tagged union pattern) – Paul Stelian Jul 04 '16 at 19:31
  • The value it self can be a union? Ok i can see how the type should have been an enum, i will change it so it becomes that way.. but how in the world can the union be the value? (Btw i suck at unions , cant find a use for them either :( :( ) – amanuel2 Jul 04 '16 at 19:38
  • _cant find a use for them either_ _(regarding unions)_. _[Look here](http://stackoverflow.com/questions/4788965/when-would-anyone-use-a-union-is-it-a-remnant-from-the-c-only-days)_. BTW, Eugene's assessment is correct. Your question (and your code snippet) should be distilled down to the issue(s) to make it clear. – ryyker Jul 04 '16 at 20:00
  • There is no point of taking a pointer of a vertex_am variable in the arguments of init_vertex. You could just declare the pointer in the stack of that function, because you are returning it. – qleguennec Jul 05 '16 at 02:11

2 Answers2

2

I have a segmentation Fault above. And i cant locate where it is

execute the code with gdb

gdb ./exec

then type 'run' and gdb will do his magic and tell you exactly where the segmentation fault is and you will be able to understand why.

From reading your code it looks like you are accessing vert.contents pointer without allocate memory for it...

vert.contents[vert.size_contents]

vert.contents is a double pointer that hasn't been allocated/initialized

Any Segmentation Fault Debugger for gcc and linux enviorment

gdb is, by far, the best I ever known..

jap jap
  • 320
  • 2
  • 15
  • Question.. it is giving me seg fault for that.. `printf ("%d", *((int*)get_val(*vert, 0) ));` ... Im trying to acess the value for the void pointer – amanuel2 Jul 04 '16 at 19:37
  • Other question: i added this at the end of the add_end function, is this what you are suppose to do? `vert->contents = malloc(sizeof(vert->contents)*2);` – amanuel2 Jul 04 '16 at 19:37
  • I don't know why you are using a double pointer (two dimensional array) but then you need to malloc in both dimensions, I would try: `vert->contents = (void **)malloc(sizeof(void)*number_of_array_elements_you_need);` Then, when you want to add an element to, lets say, the first dimension index 0 you have to do: `vert->contents[0] = (void *) malloc(sizeof(void)*number_of_array_elements);` Then, to read and write use: `vert->contents[0][0]` Two thing to think about: - Check always malloc returned value (on error it will be null) - Do you really need a two dimensional array? – jap jap Jul 04 '16 at 20:02
  • I dont want a two dimensinoal arrya.. i need an array of void pointers. jap jap. Thats why i have two stars.. one represeitning void * and the other represing an array of void pointers – amanuel2 Jul 04 '16 at 20:10
  • Ah, ok. Then you don't have to do the second malloc. Just do the first one – jap jap Jul 04 '16 at 20:38
  • My last one. Can you give me examples of Uses of Unions.. Cause seriously Unions are my weak point – amanuel2 Jul 04 '16 at 20:48
  • I have never used unions for that purpose, but [here](http://stackoverflow.com/a/252568/2352014) they use union the way you are looking for. They use it in conjunction with a enum to know what type to use. Hope it helps – jap jap Jul 05 '16 at 12:05
1

You can find the segmentation fault location by doing the following:

  • Compile with gcc -g to add debugging information
  • Run your program with gdb ./yourprogram
  • In the GDB prompt, press r to run the program
  • When it crashes, write bt to get the backtrace.

For the crash itself, it looks like you don't allocate memory for vertex_am's contents member so accessing it will lead to a crash.

SurvivalMachine
  • 7,946
  • 15
  • 57
  • 87
  • Thankyou so much. Your a lifesaver. But i have two questoins for you if you dont mind. Lets start out with the first one. That is , its saying the fault is in : vert.contents[vert.size_contents] = val; . On my add function. How would that be so? – amanuel2 Jul 04 '16 at 19:21
  • @Dsafds, I added some information into my answer about the crash. – SurvivalMachine Jul 04 '16 at 19:30
  • Ok that worked.. And i understand why. but now when im printing void* value, it is giving me seg fault for that.. `printf ("%d", *((int*)get_val(*vert, 0) ));` – amanuel2 Jul 04 '16 at 19:36
  • And btw. I added this at the start of add_end function.. is this what im supose to do? `vert->contents = malloc(sizeof(vert->contents)*2);` – amanuel2 Jul 04 '16 at 19:36