0

I am learning pointers these days and while learning generic pointers I came across an issue that if I want to increment the pointer value in a loop for both char and int***, how exactly can I do it. I can increment the pointer easily while dealing with one data type but in the following code, I want to increment the pointer value for both int and char.

while running the code I get the segmentation fault: 11 error message.

#define SIZE 3

enum type_details {is_book, is_article};
typedef struct library
{
    enum type_details type;
    void *item;
}library;

typedef struct item_details
{
    char *title;
    int pages;
}item_details;

int main(void)
{
    item_details details[SIZE];
    library library;

    // input title and pages values for three books
    details[0].title = malloc(SIZE*10);
    details[0].title = "C++";
    details[0].pages = 200;

    // book 2
    details[1].title = malloc(SIZE*10);
    details[1].title = "Java";
    details[1].pages = 300;

    //book 3
    details[2].title = malloc(SIZE*10);
    details[2].title = "Python";
    details[2].pages = 400;

    // displaying values through normal mechanism
    for (int i = 0; i < SIZE; i++)
    {
        printf("item: %i, Book %s with %i pages\n",i , details[i].title, details[i].pages);
    }

    // Displaying values using void pointer
    library.item = details;
    for (int i = 0; i < SIZE; i++)
    {
        printf("item: %i, Book %s with %i pages\n",i ,*(char**)library.item, *(int*)library.item);
         library.item = (int*)library.item + 1;       // error lies here
        library.item = (char**)library.item + 1;      // and here
    }

    free(details[0].title);
    free(details[1].title);
    free(details[2].title);

    return 0;
}


1

2 Answers 2

1

library.item points to data of type item_details, so you should treat it as such and increment it by sizeof(library.item) because there's no guarantee that sizeof(library.item) == sizeof(int*) + sizeof(char**) as your code assumes. The compiler is free to insert padding bytes into the struct.

So you could do this:

library.item = (char *)library.item + sizeof(item_details)

or:

library.item = (item_details *)library.item + 1
Sign up to request clarification or add additional context in comments.

2 Comments

'library.item = (item_details *)library.item + 1' makes a lot more sense as item_details has a size of int + char. when i ran the program now using it its not showing this output 'item: 0, Book C++ with 200 pages item: 1, Book Java with 300 pages item: 2, Book Python with 400 pages item: 0, Book C++ with -1572852592 pages item: 1, Book Java with -1572852560 pages item: 2, Book Python with -1572852528 pages'
if you can see the pages has some garbage value
1

details[0].title = malloc(SIZE*10); followed by details[0].title = "C++"; is WRONG: You just allocated storage to details[0].title and then you throw that pointer away and replace it with a pointer to the literal string "C++".

free(details[0].title); will next case the seg fault because you want to free something not allocated with malloc.

You must use strcpy: strcpy(details[0].title,"C++");

See also the solution by ForceBru, who also raises a valid point and problem.

3 Comments

Thanks for the suggestion, but without using details[0].title = malloc(SIZE*10); i get segmentation fault.
@OwaisQayyum okay, it's still wrong, you probably get segmentation fault because of how you're trying to increment the pointer
You must keep the malloc call of course (you need the memory) and then copy the string value to the newly allocated memory.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.