Getting a seg-fault when setting value of pointer - c

There really isnt much I can say here.
Here is my lexer file:
#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;
}
}
And here is my vector file:
#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);
}
When I run the code above, I get a Seg-Fault.
How can this be happening? Here is the output of gdb:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400656 in vector_new (v=0x1) at vector.h:14
14 v->capacity = 4;
As you can see, its segfaulting when i set the vector capacity!
But why?

It segfaults because you dereference a garbage pointer:
vector* get_tokens(char* in)
{
vector *toks;
vector_new(toks);
The variable toks is not assigned to anything meaningful, just whatever garbage value happens to be floating about. This gets passed into vector_new() which immediately dereferences it:
void vector_new(vector *v)
{
v->capacity = 4;
Then BAM! it blows up because v points nowhere appropriate.
Try mallocing a vector before making your call to vector_new() or put the malloc in vector_new() and have it return the pointer to the new vector instead. It's also a good idea to check the return value from malloc().
You might try something like:
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;
}
Then change how you call it:
vector* get_tokens(char* in)
{
vector *toks;
toks = vector_new();
And for every malloc(), let there be a free(). Don't forget to clean up this allocation too or you'll leak memory:
void vector_free(vector *v)
{
free(v->items);
free(v);
}
(You defined a vector_free(), but never called it. You might want to consider doing that too.)

invalid pointer dereference happened
vector *toks;
vector_new(toks);
Should be
vector *toks = (vector*)malloc(sizeof(vector));
vector_new(toks);

Related

how can I iterate through an array of generic type (void**) in with function pointer in C?

I want to perform a simple task working with function pointers in C.
The task is to get an array (from any type, i.e: int / char*), and sum /concatenate each 2 elements in the array.
for the char* type, it works fine, but for the int type, the loop seems to jump each 2 elements in the array (and thus overflow the array):
#define N1 4
#define N2 4
typedef void*(*Fn_Sum)(void*, void*);
typedef void(Fn_Prt)(void*);
int sum_num(int a, int b){
return a + b;
}
char* sum_char(char* a, char* b){
char *result = malloc(strlen(a) + strlen(b) + 1);
if (!result) {
printf("ERROR: malloc failed !\n");
return NULL;
}
strcpy(result, a);
strcat(result, b);
return result;
}
void print_num(int a){
printf("%d", a);
}
void print_string(char* a){
int i = 0;
while (a[i] != '\0') {
printf("%c", a[i]);
i++;
}
}
void PrintSums(void** P, int n, Fn_Sum fsum, Fn_Prt fprt){
for(int i = 0; i < n - 1; i++){
(fprt)(fsum(P[i], P[i+1]));
printf(", ");
}
printf("\n");
}
int main() {
int V[N1] = {1,2,3,4};
char* S[N2] = {"a", "d", "c", "d"};
PrintSums(V, N1, sum_num, print_num);
PrintSums(S, N2, sum_char, print_string);
return 0;
}
expected output is :
3, 5, 7,
ab, bc, cd,
actual outputs:
4, 725939, 4925336,
ad, dc, cd,
Create an abstract interface for iterator over the elements. A draft of such interface could look like this:
struct iterator {
...
};
// ptr - a pointer to beginning of the array
// size - size of one element in the array
void it_init(iterator *t, void *ptr, size_t size);
bool it_eq(iterator *t, iterator *o); // compare iteratores
void it_add(iterator *t, size_t n);
void it_inc(iterator *t);
// return a pointer to the element
void *it_get(iterator *t);
Remember to always pass to user callbacks a context variables. Otherwise users will have to use global variables, which make code messy. Create an abstract interface with destructors and constructors of your summing object. Handle errors properly:
// is passed a pointer to user context
// returns 0 on success
typedef int (*Fn_Sum)(void*, void*);
// is passed a pointer to user context
// returns 0 on success
typedef int (Fn_Prt)(void*);
// returns 0 on success
int PrintSums(iterator it, size_t n, Fn_Sum fsum, Fn_Prt fprt, void *sumctx);
After that, implement objects that expose the interface that you want:
struct num { .. };
void num_sum(struct num *t, int el);
void num_print(struct num *t, int el);
// expose interface to PrintSums
// that just calls internal api
int num_PrintSums_Fn_Sum(void *ctx, void *el0) {
struct num *t = ctx;
int *el = el0;
num_sum(t, *el);
return 0;
}
int num_PrintSums_Fn_Prt(void *ctx) {
struct num *t = ctx;
num_print(t);
return 0;
}
An example whole program looks like this:
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// iterator
typedef struct iterator {
void *ptr;
size_t size;
} iterator;
void it_init(iterator *t, void *ptr, size_t size) {
*t = (iterator){ ptr, size, };
}
// eq is from test(1) shell command. "eq" means "equal"
bool it_eq(iterator *t, iterator *o) {
return t->ptr == o->ptr;
}
void it_add(iterator *t, size_t n) {
t->ptr = (char*)t->ptr + t->size * n;
}
// increment the iterator
void it_inc(iterator *t) {
it_add(t, 1);
}
// return a pointer to the element
void *it_get(iterator *t) {
return t->ptr;
}
// interface
typedef int (*Fn_Sum)(void*, void*);
typedef int (Fn_Prt)(void*);
int PrintSums(iterator it, size_t n, Fn_Sum fsum, Fn_Prt fprt, void *sumctx){
iterator end = it;
it_add(&end, n);
for(; !it_eq(&it, &end); it_inc(&it)) {
int err = fsum(sumctx, it_get(&it));
if (err) return err;
err = fprt(sumctx);
if (err) return err;
printf(", ");
}
printf("\n");
return 0;
}
// num object
struct num {
int sum;
};
void num_init(struct num *t) {
t->sum = 0;
}
void num_sum(struct num *t, int el){
t->sum += el;
}
void num_print(struct num *t){
printf("%d", t->sum);
}
void num_free(struct num *T) {
// nothing, just exists for uniform API
}
// accessors for PrintSums
int num_PrintSums_Fn_Sum(void *ctx, void *el0) {
struct num *t = ctx;
int *el = el0;
num_sum(t, *el);
return 0;
}
int num_PrintSums_Fn_Prt(void *ctx) {
struct num *t = ctx;
num_print(t);
return 0;
}
// string object
struct str {
char *str;
};
void str_init(struct str *t) {
t->str = NULL;
}
int str_sum(struct str *t, const char *str) {
const size_t str_len = t->str == NULL ? 0 : strlen(t->str);
void *p = realloc(t->str, str_len + strlen(str) + 1);
if (p == NULL) {
free(t->str);
t->str = NULL;
return -1;
}
t->str = p;
memcpy(t->str + str_len, str, strlen(str) + 1);
return 0;
}
void str_print(struct str *t) {
if (t->str == NULL) {
printf("(nul)");
} else {
printf("%s", t->str);
}
}
void str_free(struct str *t) {
free(t->str);
}
// interface for PrintSums
int str_PrintSums_Fn_Sum(void *ctx, void *el0) {
struct str *t = ctx;
const char **el = el0;
str_sum(t, *el);
return 0;
}
int str_PrintSums_Fn_Prt(void *ctx) {
struct str *t = ctx;
str_print(t);
return 0;
}
// and finally main
int main() {
int err = 0;
int V[] = {1,2,3,4};
iterator numit;
it_init(&numit, V, sizeof(*V));
struct num numsum; // the object that will hold the sum
num_init(&numsum);
err = PrintSums(numit, sizeof(V)/sizeof(*V), num_PrintSums_Fn_Sum, num_PrintSums_Fn_Prt, &numsum);
if (err) abort();
num_free(&numsum);
char *S[] = {"a", "d", "c", "d"};
iterator strit;
it_init(&strit, S, sizeof(*S));
struct str strsum; // the object that will hold the sum of strings
str_init(&strsum);
err = PrintSums(strit, sizeof(S)/sizeof(*S), str_PrintSums_Fn_Sum, str_PrintSums_Fn_Prt, &strsum);
if (err) abort();
str_free(&strsum); // YES! Remember to pick out the trash
}
and outputs on godbolt:
1, 3, 6, 10,
a, ad, adc, adcd,
The pointers to a constructor and destructor of "sum objects" could be passed to PrintSums too. That said one could start thinking about creating a virtual table for all these pointers (ie. one struct with function pointers that are needed for PrintSums...).

Problems with qsort() with struct containing char*

table.h:
#ifndef table_h
#define table_h
// The object:
typedef struct Pair
{
char* name;
int number;
} Pair;
int comp_pair(const void* lhs, const void* rhs)
{
Pair* lp = (Pair*) lhs;
Pair* rp = (Pair*) rhs;
const char* ln = lp->name;
const char* rn = rp->name;
return strcmp(ln, rn);
}
// The array and associated functions:
size_t table_capacity;
size_t table_size;
Pair* table; // <------ Global variables -------------------
Pair* create_table (size_t capacity)
{
Pair* p = 0;
p = (Pair*) malloc(sizeof(*p) * capacity);
if (p == NULL && capacity > 0)
{
perror("create_table()::bad allocation!\n");
exit(-1);
}
table_capacity = capacity;
return p;
}
void insert (Pair* table, const char* name, int number)
{
Pair* p = (Pair*) malloc(sizeof(*p));
if (p == NULL)
{
perror("insert::bad allocation!\n");
exit(-1);
}
p->name = name;
p->number = number;
table[table_size++] = *p;
}
void print_table(Pair p[], size_t size)
{
size_t i = 0;
for (i; i < size; ++i)
{
printf("%s -> %d\n", p[i].name, p[i].number);
}
}
#endif
main.c:
#include <stdio.h>
#include <stdlib.h> // qsort()
#include <string.h> // strcmp()
#include <stddef.h> // size_t
#include "table.h"
int main()
{
char* names [ ] = { "bla1", "bla2", "bla3", "bla4", "bla5"};
int numbers [ ] = { 1, 2, 3, 4, 5 };
size_t s = 5;
size_t i = 0;
table = create_table(s);
for (i; i < s; ++i)
{
insert(table, names[i], numbers[i]);
}
qsort(table, table_size, sizeof(Pair), comp_pair);
print_table(table, table_size);
getchar();
free(table);
}
When I try to use qsort(), (debugging) the above code generates the following error:
Access violation reading location 0x65727541.
Questions:
Is the function comp_pair() correct?
What size should I pass as a third parameter in qsort(), the current sizeof(Pair) or the size of the actually compared types, i.e. char*?

Array of Struct Pointers (C Programming) Issues

So i'm trying to figure out how to do a few different things and I haven't worked with C that much, so any help would be much appreciated.
typedef int data_t;
typedef struct set {
data_t *array;
size_t capacity;
size_t size;
} set_t;
typedef data_t* set_i_t;
#define CLEAR -1
I have gotten this method working which uses malloc and allocates memory:
int set_init( set_t *set, int capacity ){
set->array = (data_t*)malloc(capacity * sizeof(data_t));
if(set->array == NULL){
return 1;
}
else{
set->capacity = capacity;
set->size = 0;
return 0;
}
}
And a method which frees it:
void set_free( set_t *set ){
free(set->array);
set->array = NULL;
set->capacity = set->size = 0;
}
In a separate method i'm trying to set all the values in the set to -1 (CLEAR)
void set_clear( set_t *set){
int i = 0;
for (i = 0; i < set->size; i++){
set->array = CLEAR;
}
set->size = 0;
}
Return the Size of the set:
int set_size( set_t set ) {
return sizeof(set->array);
}
Return the capacity:
int set_capacity( set_t set ) {
int capacity = set->capacity;
return capacity;
}
And then print the set:
void set_print( set_t set ) {
//Honestly don't feel like i'm ready for this one yet.
}
If anyone could walk me through a couple of these or give me a little assistance on how these can work, that would be awesome. Thanks guys!
A good resource is C dynamically growing array
1
You can read about size_t. What is size_t in C?
typedef int data_t;
// Here you are redefining int to data_t this is then used in array.
typedef struct set {
data_t *array;
// The address on heap where the typedef data_t is stored
size_t capacity;
size_t size;
} set_t;
typedef data_t* set_i_t;
// not sure why this is here maybe you use somewhere else
#define CLEAR -1
2
set_free( set_t *set); Looks good to me.
set_init(); yes but no
set_t set_init(int capacity) {
// create it here then return it.
set_t ret;
ret.array = (data_t*)malloc(capacity * sizeof(data_t));
if (ret.array == NULL) return NULL;
ret.capacity = capacity;
ret.size = 0;
return ret;
}
In the calling function
set_t A = set_init(5);
if (A == NULL) fprintf(stderr, "could not alloc memory\n");
// :)
3
void set_clear( set_t *set){
// you pass the address of the struct into the function. you could also use set_i_t
//int i = 0;
// why do this you can do it in the for loop as you can see
// for (i = 0; i < set->size; i++){
for (int i = 0; i < set->size; i++){
//set->array = CLEAR; common mistake
// you are saying the address of the array. aka array[0]
// this is the same as set->(array+i)
set->array[i] = CLEAR;
}
set->size = 0;
}
4 & 5
// looks good but again better ways of doing this.
set_size( set_t set );
set_capacity( set_t set );
Better ways of managing memory such as in the example here. C dynamically growing array
6
read all about printf();
http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm
void set_print( set_t set ) {
// Here you passed the struct in plain and simple no pointer......
// so you will use the '.' not the '->'
// Here we can take a look at printf();
// %d is used to print int variables.
// to start off you know you will have to loop through the array.
for (int i = 0; i < set.size; i++) {
// you know the array must be at least have one item in it.
printf("%d\n", set.array[i]);
// using printf print the data_t aka "int" item in the array
}
}
Hope this helps. G
There were a few places where you defined the function arguments with set_t instead of set_t *.
Your set_size would just return the size of the array pointer (i.e. always 4 or 8), so that needed set->size
Also, set_clear was incorrect [and wouldn't even compile].
I've added some functions and implemented the [dreaded :-)] print function. No worries ...
Anyway, here's the corrected code [please pardon the gratuitous style cleanup]:
#include <stdio.h>
#include <malloc.h>
typedef int data_t;
typedef struct set {
data_t *array; // pointer to set's data
size_t capacity; // total number of data slots
size_t size; // number of slots currently in use
} set_t;
typedef data_t *set_i_t;
#define CLEAR -1
int
set_init(set_t *set, int capacity)
{
set->array = (data_t *) malloc(capacity * sizeof(data_t));
if (set->array == NULL) {
return 1;
}
else {
set->capacity = capacity;
set->size = 0;
return 0;
}
}
// And a method which frees it:
void
set_free(set_t *set)
{
free(set->array);
set->array = NULL;
set->capacity = set->size = 0;
}
// i'm trying to set all the values in the set to -1 (CLEAR)
void
set_clear(set_t *set)
{
int i = 0;
for (i = 0; i < set->size; i++) {
#if 0
set->array = CLEAR;
#else
set->array[i] = CLEAR;
#endif
}
set->size = 0;
}
// Return the Size of the set:
int
set_size(set_t *set)
{
return set->size;
}
// Return the maximum capacity:
int
set_capacity_max(set_t *set)
{
int capacity = set->capacity;
return capacity;
}
// Return the remaining available capacity:
int
set_capacity_avail(set_t *set)
{
int capacity = set->capacity - set->size;
return capacity;
}
// add some data
void
set_append(set_t *set,int val)
{
// NOTES:
// (1) this does _not_ check for overflow against capacity
// (2) when out of capacity, we might increase capacity and do a realloc
// on array
#if 0
if ((set->size + 1) >= set->capacity) {
set->capacity += 100;
set->array = realloc(set->array,sizeof(data_t) * set->capacity);
}
#endif
set->array[set->size++] = val;
}
// And then print the set:
void
set_print(set_t *set)
{
int i;
int len;
// Honestly don't feel like i'm ready for this one yet.
// Relax, no worries ...
len = 0;
for (i = 0; i < set->size; i++) {
len += printf(" %d",set->array[i]);
if (len >= 72) {
printf("\n");
len = 0;
}
}
if (len > 0)
printf("\n");
}
int
main(void)
{
set_t myset;
set_init(&myset,100);
set_append(&myset,17);
set_append(&myset,23);
set_append(&myset,37);
set_print(&myset);
set_free(&myset);
return 0;
}

Function to read in a word into a struct array

I am having an error with the code we are using, was wondering if someone could help debug. Seems like we are getting a malloc error. Thanks.
void readWords(char norm_word[MAXSIZE], Word ** array) {
int i = 0;
bool found = false;
int result = 0;
Word * current_pointer = malloc (sizeof(Word*));//creates a temporary variable for each pointer in the array
for (i=0; i<word_counter; i++) {
current_pointer = *(array+i); //accesses the current pointer
result = strcmp(norm_word, (current_pointer -> word)); //compares the string to each stored string
if (result == 0) {
found = true;
(current_pointer->freq)++;
break;
}
}
if(!found) {
if(pointer_counter == word_counter) {
array = realloc(array, sizeof(array)*2);
pointer_counter*=2;
}
Word * new_pointer = (Word*) malloc (sizeof(Word*));
strcpy(new_pointer -> word, norm_word);
*(array + (pointer_counter - 1)) = new_pointer;
word_counter++;
}
;
}
All pointers have the same size on your system. So a sizeof always returns the same size for any pointer. You want to allocate for the structure, so you need to use sizeof on the name without the star. malloc will return the pointer to that block of memory afterwards.
Here is a short implementation:
#include <iostream>
#include <string>
typedef struct
{
int num;
int numnum;
}numbers;
int main(int argc, char ** argv)
{
numbers* n = (numbers*)malloc(sizeof(numbers));
n->num = 1;
n->numnum = 2;
free(n);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAXSIZE 64
typedef struct word {
char word[MAXSIZE];
int freq;
} Word;
int word_counter = 0;
size_t pointer_counter = 16;//Number of pointers that ensure
void readWords(char norm_word[MAXSIZE], Word ** array) {
int i = 0;
bool found = false;
Word *current_pointer = *array;
for (i=0; i<word_counter; i++) {
if(strcmp(norm_word, current_pointer->word) == 0){
found = true;
current_pointer->freq++;
break;
}
++current_pointer;
}
if(!found) {
if(pointer_counter == word_counter) {
pointer_counter *= 2;
*array = realloc(*array, sizeof(Word)*pointer_counter);
}
Word *new_pointer = *array + word_counter;
new_pointer->freq = 1;
strcpy(new_pointer->word, norm_word);
++word_counter;
}
}
int main(void){
Word *vocabulary = calloc(pointer_counter, sizeof(Word));
char norm_word[MAXSIZE];
while(1==scanf("%s", norm_word)){
readWords(norm_word, &vocabulary);
}
{
int i;
for(i = 0; i < word_counter; ++i){
printf("%s(%d)\n", vocabulary[i].word, vocabulary[i].freq);
}
}
free(vocabulary);
return 0;
}

Segmentation Fault at WHILE loop

I am trying to read in a text file, which contains integers, and place them into an array. I will be sorting them once I have the array created. However, I trying to make sure things work as I implement them but I am getting a segmentation fault when I attempt to open a file. I do not understand why.
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#define SIZE_T_MAX 16777216
/****** FORWARD DECLARATIONS ******/
void die(const char *message) {
if(errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
// ARRAY
typedef struct int_array {
int *array;
size_t length;
size_t capacity;
} int_array;
void int_array_init(int_array *array);
void int_array_free(int_array *array);
void int_array_add(int_array *array, int value);
/****** END OF DECLARATIONS ******/
//
//
/********** MAIN PROGRAM **********/
int main(char argc, char *argv[]) {
// VARIABLES
FILE *data;
int_array numbers;
int_array_init(&numbers);
int i = 0;
char value[10];
// LOAD FILES
printf("Loading files...\n");
data = fopen("list0.txt", "r");
if(data == NULL) die("Failed to load file.");
while(!feof(data) && !ferror(data)) {
fscanf(data, "%s", value);
int_array_add(&numbers, atoi(value));
printf("%d", numbers.array[i]);
i++;
}
// CLEAN UP
int_array_free(&numbers);
fclose(data);
return 0;
}
/*********** END OF MAIN **********/
//
//
/******* ADDITIONAL METHODS *******/
void int_array_init(int_array *array) {
array->array = NULL;
array->length = 0;
array->capacity = 0;
}
void int_array_free(int_array *array) {
free(array->array);
array->array = NULL;
array->length = 0;
array->capacity = 0;
}
void int_array_add(int_array *array, int value) {
if (array->length == array-> capacity)
{
int new_capacity;
if (array->capacity == 0) new_capacity = 10;
else new_capacity = array->capacity * 2;
if (new_capacity > array->capacity && new_capacity < SIZE_T_MAX / sizeof(int)) {
int *new_array = realloc(array->array, new_capacity * sizeof(int));
if (new_array != NULL) {
array->array = new_array;
array->capacity = new_capacity;
} else {
die("Out of Memory");
}
} else {
die("Overflow.");
}
}
array->array[array->length] = value;
array->length++;
}
I have corrected and fixed my code. The problem was in the while loop being infinite and corrected with:
while(!feof(data) && !ferror(data))

Resources