Home > Software engineering >  C Program bump into segmentation fault. (gdb) Cannot access memory at address
C Program bump into segmentation fault. (gdb) Cannot access memory at address

Time:09-21

I am trying to write codes in C for dynamic array (vector), and it runs okay until I add another function pointer into the struct (line29: int (findEle)(vector, int) ), and initialize it (line 153: v->findEle = findEle) to point to the function implementation (line 125: int findEle(vector* v, int value)). The debugger starts returning segmentation fault every time I tried to run it. Please find the code below:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int BOOL;
#define TRUE 1
#define FALSE 0


typedef struct Vector vector;

struct Vector
{
    int currCapacity;
    int currSize;
    int *items;
    // TODO: Try to add another int field, will cause seg fault

    int (*size)(vector*);
    int (*capacity)(vector*);
    BOOL (*is_empty)(vector*);
    void *(*at)(vector*, int);
    void (*push)(vector*, int);
    void (*insert)(vector*, int, int);
    void (*resize)(vector*, size_t);
    int (*pop)(vector*);
    void (*removeValue)(vector*, int);
    void (*delete_ele)(vector*, int);
    int (*findEle)(vector*, int);
};


// Vector Functions
int size(vector *v)
{
    return v->currSize;
}

int capacity(vector *v)
{
    return v->currCapacity;
}

BOOL is_empty(vector *v)
{
    if(v->currSize==0){ return TRUE; }
    return FALSE;
}

void *at(vector *v, int index)
{
    if(index >= v->currSize){return NULL;}
    return (int*)(v->items index);
}

void push(vector *v, int item)
{
    if(v->currSize == v->currCapacity)
    {
        v->items = (int*)realloc(v->items, sizeof(int)* (v->currCapacity * 2));
        v->currCapacity = v->currCapacity * 2;
    }
    *(v->items v->currSize) = item;
    v->currSize  ;
}

void insert(vector* v, int index, int item)
{
    printf("Inserting %d at index %d\n", item, index);
    if(v->currSize == v->currCapacity)
    {
        v->items = (int*)realloc(v->items, sizeof(int)* (v->currCapacity * 2));
        printf("v->items address: %p\n", v->items);
        v->currCapacity = v->currCapacity * 2;
    }
    int* shift_ptr = v->items index;
    memmove(v->items index 1, v->items index, sizeof(int)*(v->currSize-index));
    *(v->items index) = item;   
    v->currSize  ;
}

void resize(vector* v, size_t size)
{
    printf("Resizing from %d to %d\n", v->currSize, size);
    v->items = (int*)realloc(v->items, sizeof(int)* size);
}

int pop(vector* v)
{
    int last = *(v->items   (v->currSize-1));
    v->currSize--;
    if(v->currSize*4 == v->currCapacity)
    {
        v->resize(v, v->currCapacity/2);
    }
    return last;
}

void delete_ele(vector* v, int index)
{
    int *curr_ptr = v->items index;
    if(v->currSize*4 == v->currCapacity)
    {
        v->resize(v, v->currCapacity/2);
    }
    memmove(curr_ptr, curr_ptr 1, sizeof(int)*(v->currSize-(index 1)));
    v->currSize--;
}

void removeValue(vector *v, int value)
{
    for(int i=0; i<v->currSize; i  )
    {
        int ptr_value = *(v->items i);
        printf("%d->%d ", i, ptr_value);
        if(ptr_value==value)
        {
            delete_ele(v, i);
            --i;
        }
    }
    printf("\n");
}

int findEle(vector* v, int value)
{
    for(int i=0; i<v->currSize; i  )
    {
        if(*(v->items i)==value)
        {
            return i;
        }
    }
    return -1;
}

vector *initializeVector()
{
    vector *v;
    v->currSize = 0;
    v->currCapacity = 2;
    v->items = (int*)malloc(sizeof(int) * v->currCapacity);

    v->size = size;
    v->capacity = capacity;
    v->is_empty = is_empty;
    v->at = at;
    v->push = push;
    v->insert = insert;
    v->pop = pop;
    v->removeValue = removeValue;
    v->delete_ele = delete_ele;
    v->findEle = findEle;
    return v;
}


int main()
{
    vector *v = initializeVector();
    v->push(v, 8);
    v->push(v, 25);
    v->push(v, 25);
    v->push(v, 12);
    printf("element 0 :%d\n", *(int*)v->at(v, 0));
    printf("element 1 :%d\n", *(int*)v->at(v, 1));
    printf("element 2 :%d\n", *(int*)v->at(v, 2));
    printf("element 3 :%d\n", *(int*)v->at(v, 3));
    v->insert(v, 1, 50);
    printf("element 0 :%d\n", *(int*)v->at(v, 0));
    printf("element 1 :%d\n", *(int*)v->at(v, 1));
    printf("element 2 :%d\n", *(int*)v->at(v, 2));
    printf("element 3 :%d\n", *(int*)v->at(v, 3));
    printf("element 4 :%d\n", *(int*)v->at(v, 4));
    //printf("%d\n", v->pop(v));
    printf("%d\n", v->findEle(v, 25));
    v->removeValue(v, 25);
    for(int i=0; i<v->currSize; i  )
    {
        int ptr_value = *(v->items i);
        printf("%d->%d ", i, ptr_value);
    }
    free(v->items);
    return 0;
}

I tried to debug using gdb, it returns the below message:

Program received signal SIGSEGV, Segmentation fault. 0x0040189a in initializeVector () at Vector.c:153 153 v->findEle = findEle;

When I tried to get the address of the stated function, it showed the message below: (gdb) x v->findEle Cannot access memory at address 0x620000

Can someone kindly advice if I have some issues on memory allocation? Or the issue might be due to some other causes? Thanks!

CodePudding user response:

At least in these functions

void resize(vector* v, size_t size)
{
    printf("Resizing from %d to %d\n", v->currSize, size);
    v->items = (int*)realloc(v->items, sizeof(int)* size);
}

int pop(vector* v)
{
    int last = *(v->items   (v->currSize-1));
    v->currSize--;
    if(v->currSize*4 == v->currCapacity)
    {
        v->resize(v, v->currCapacity/2);
    }
    return last;
}

void delete_ele(vector* v, int index)
{
    int *curr_ptr = v->items index;
    if(v->currSize*4 == v->currCapacity)
    {
        v->resize(v, v->currCapacity/2);
    }
    memmove(curr_ptr, curr_ptr 1, sizeof(int)*(v->currSize-(index 1)));
    v->currSize--;
}

you do not update data members currCapacity and currSize

And in this function

vector *initializeVector()
{
    vector *v;
    v->currSize = 0;
    v->currCapacity = 2;
    v->items = (int*)malloc(sizeof(int) * v->currCapacity);

    v->size = size;
    v->capacity = capacity;
    v->is_empty = is_empty;
    v->at = at;
    v->push = push;
    v->insert = insert;
    v->pop = pop;
    v->removeValue = removeValue;
    v->delete_ele = delete_ele;
    v->findEle = findEle;
    return v;
}

there is used the uninitialized pointer v that has an indeterminate value that results in undefined behavior.

Also you need to check the value of the parameter index in each function where it is used.

  • Related