0

The program works fine when I dynamically allocated memory in "main" function. Now I want to allocate in "read" function, but every attempt I fail miserably.

I think that my problem is in my "main" function: I can't figure out how to retrive a structure (pointer) from function "read" and then free it's dynamically allocated memory by function "destroy".

int main(void)
{
    int err_code;
    struct student_t** s=(struct student_t**)malloc(1024*sizeof(struct student_t*));
    **s = &read(err_code); //here is: error: lvalue required as unary '&' operand.
    //But I think that my problem is wider than just this error.

    if (s==NULL) {
        puts("Error\n");
    }

    display(s);
    destroy(s);

    return err_code;
}


What I tried to do: create a pointer of struct type, pointing to pointer to the structure, returned by "read" function. Then pass this **pointer to "destroy" function, to free the malloc'ed memory.

Functions.
In function "read" users inserts data that is assigned to a structure. Returns pointer to the dynamically allocated structure or NULL if there was any error.

struct student_t* read(int *err_code)
{   printf("Insert data:\n");
    struct student_t* p = (struct student_t *)malloc(1024*sizeof(struct student_t));
    *err_code=1;
    if (p==NULL) {
        puts("Error\n");
        return NULL;
    }
//then it's supposed to read from user and assing to struct. Code below in links.
}


struct student_t {
    char name[20];
    char surname[40];
    int index;
};


Fuction frees dynamically allocated memory, unless "read" failed and returned NULL.

void destroy(struct student_t **s)
{
if (s!=NULL) free(s);
}


My display function. But my problems begin earlier, I think.

void display(const struct student_t **s) //here I'm unsure if it should be *s- or **s-function.
{
    if(s!=NULL) printf("%s %s, %i\n", (*s)->name, (*s)->surname, (*s)->index);
}

My "read" function is based on answers for my previous questions. It works when I properly allocated memory in "main". The code for "read" I use: How to detect if user inserts data with commas (in a desired format) or not? Other simplier "read" with which I was unable to handle all errors I wanted properly: How to scanf commas, but with commas not assigned to a structure? C

I really appreciate all help, everything is like a salvation for my 150 hours struggle with one task.

Immo
  • 19
  • 6
  • 1
    Please make up your mind. Do you want to work with an array of `student_t` (what's your `read` function does) or with an array of `student_t*` (what's the rest of your code does)? These are different things and you cannot do a U-turn and change your mind mid-code. You need to decide before you start writing a line of code, and stick to your decision. Your array should be either `student_t*` or `student_t**` all the way through. – n. m. could be an AI Aug 20 '18 at 20:28
  • Thanks! Fixing "display" to work on array of `student_t` instead of `student_t*` and with the answer from Some programmer dude fixed my code's errors and returning values like `-12841928` just after typing from keyboard. – Immo Aug 20 '18 at 20:49

1 Answers1

2

You have two errors:

  1. The one you ask about is because you're doing it all wrong. The value returned by a function is a so-called r-value. It's so named because it can only be on the right-hand side of an assignment. It's a little more complicated than that, but the common test for an r-value or an l-value (something you can assign to, the left-hand side) is if its address can be taken with the address-of operator &. R-values can not have an address taken.

    The (simple) solution to this is simple:

    *s = read(err_code);
    
  2. The second error is because read expects a pointer to an int as its argument, while you pass a plain int variable. Here you should use the address-of operator:

    *s = read(&err_code);
    

There are a few other problems, the biggest being the need for s to be a pointer to a pointer. Can't it just be a single-pointer, and then simply do

    struct student_t *s = read(&err_code);

Another problem is that in many systems there might already be an existing read function (most notably POSIX systems like Linux and macOS), so you will have conflicting declarations for that function.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621