Home > database >  Struct member array; creation and access through use of return pointer type function
Struct member array; creation and access through use of return pointer type function

Time:12-13

Preface.

This is my first question here, so sorry if it doesn't conform to a standard format or way of phrasing a question etc. I'm not ignorant to the fact that this probably has been answered somewhere in the depths, but I've searched through the best of my ability and I couldn't find anything that was similar enough in such a way that it helped me understand what I was doing wrong.

I'm fairly new at C, have programming experience but I do lack large chunks of fundamentals. Which will show through my attempts at explaining and describing the problem. I appreciate the feedback, but I honestly have a very low aptitude for understanding computer science definitions, so would appreciate applied examples as opposed to a quote. Thanks in advance for the extra trouble!


Ok, so for the actual problem;

I am trying to create a list without using list() at all, so far I've gotten to the point where I want to confirm I'm actually doing it.

  • Create a function that returns a struct with the list/array of whatever length I want it to be.
  • Check that the function does what I want it to do by seeing if the content of the struct member elements is the content of arraytest..

header includes the following

//header 

typedef struct {
    size_t length;
    int elements[];
}list_t;

list_t *new_list(size_t length, int elements[]); 

Source file so far (forego include/defines because it really isn't relevant here)

list_t *new_list(size_t length, int elements[])
{
    list_t* newList = (list_t*)malloc(sizeof(list_t*)   sizeof(int) * length);
    
    newList->length = length;
    newList->elements[length - 1];

    return newList;
}


int main()
{
    int arraytest[] = {1, 2, 3, 4, 5}; 
    int length      = 6;
    
    list_t* list = new_list(length, arraytest);

    for(int i = 0; i < length; i  )
    {
        printf("The address of [%d] element : %p\n", i, &list->elements[i]);
        printf("The value of [%d] element : %u\n", i, list->elements[i]);
        printf("The pointer value of [%d] element : %p\n", i, list->elements[i]);
        printf("No [] index iteration of [%d] element : %p\n", i, list->elements);
    }
   
    return 0;
}

As can be seen from the main, I have tried to mentally grasp at different things that I have thought may be the cause for my ?confusion? on this..

I'm obviously trying to confirm that I actually have my array by printing the elements, accessible by index.
Normally, I've done this in structs before but always with a predefined size and never through a function pointer return (or with a array parameter for that matter). Its for the most part gone ok, and I've not had any issues.

However, I guess what I'm trying to get at here is WHAT am I essentially missing?

I thought of a few things;

  1. Either I'm missing the fact that C uses pass by value and that somehow the function return pointer isn't being treated as such, either in the main or by the function new_list itself, I don't really know.

  2. The syntax I'm using is not the correct one for the confirmation I'm trying to get, I already have what I want and I'm missing something extremely trivial.

  3. The function *new_list is wrong and I'm not returning a what I think I'm returning.

  4. Any combination of the above and probably something else, or something else entirely.

I have tried from the prints to see whether or not its a dereferencing thing, but since I'm already using arrays I've honestly just tried to throw in a few different things since I feel the distinction with respect to arrays and pointers are not 100% clear.

For example I know, or rather I think I know the distinction between using * as a pointer vs a dereferencing operator, get address of & and -> is used for struct member access and so on, that's clear to me I suppose. But I cant say I honestly get it once you throw in arrays in the mix.

Regardless, I'm gonna stop there, I think this gets the point across ( ).

oh and the program executes and runs, I don't get any errors, only some compiler warnings about formatting, which shouldn't really be the issue I think.

Again, thanks for the help !

CodePudding user response:

  • list_t* newList = (list_t*)malloc(sizeof(list_t*) sizeof(int) * length); is wrong, should be sizeof(list_t) ....
  • newList->elements[length - 1]; is a no-op, it has no side effects and the compiler should tell you as much. What compiler options are recommended for beginners learning C? You probably meant to set the item to zero.
  • Ideally check if malloc didn't succeed and returned NULL.
  • new_list(length, arraytest); You lie to the function and say that you pass 6 items when you only pass 5.
  • printf("The pointer value of [%d] element : %p\n", i, list->elements[i]); doesn't make sense, this isn't a pointer. As already established in your first printf line, you'd have to write &list->elements[i] to get an address. Same problem in several printf statements.
  • free() all dynamically allocated items when you are done using them.

CodePudding user response:

I would use realloc to make the function more universal. @Lundin made a nice list of errors in your code so I will not repeat it in this answer

typedef struct {
    size_t length;
    int elements[];
}list_t;

list_t *addToList(list_t *list, size_t length, const int *elements)
{
    size_t newLength = list ? list -> length   length : length;

    list = realloc(list, sizeof(*list)   newLength * sizeof(list -> elements[0]));
    if(list)
    {
        size_t startPos = newLength == length ? 0 : list -> length;
        for(size_t pos = startPos; pos < newLength; pos  )
        {
            list -> elements[pos] = *elements  ;
        }
        list -> length = newLength;
    }
    return list;
} 


int main(void)
{
    int arraytest[] = {1, 2, 3, 4, 5}; 
    size_t length = sizeof(arraytest) / sizeof(arraytest[0]);
    
    list_t* list = NULL; 

    for(int i = 0; i < 5; i  )
    {
        list_t *tmp = addToList(list, length, arraytest);
        if(tmp)
        {
            list = tmp;
            printf("List length %zu\n Elements:", list -> length);
            for(size_t pos = 0; pos < list -> length; pos  )
                printf("%d ", list -> elements[pos]);
            printf("\n");
        }
        for(size_t pos = 0; pos < length; pos  ) arraytest[pos] = arraytest[length - 1]   pos   1;
    }
}

https://godbolt.org/z/P3rdPjM6o

  •  Tags:  
  • c
  • Related