0

I want to allocate memory for "title" dynamically as I don't know how long the titles will be. I have the following code:

#include<stdio.h>
#include<malloc.h>

struct film {
    char title[500];
    int year;
    int duration;
    int earnings;
};

void main() {
    int n;
    scanf("%d", &n);
    int array[n], i = 0;
    struct film user[n];

    while (i < n) {
        scanf("%s", &user[i].title);
        scanf("%d", &user[i].year);
        scanf("%d", &user[i].duration);
        scanf("%d", &user[i].earnings);
        i += 1;
    }
}

I tried replacing:

char title[500];

with:

char *title = (char*)malloc(sizeof(char));

However, it didn't work. It says that it expects something else before "=". Also, how do I scanf the input from the user for title if it is dynamically allocated?

How do I free the memory later? I assume it's as below:

void freememory(struct film target,  n) { //n is size of structure
    int i = 0;
    while (i < n) {
        free(target[i].title);
        i += 1;
    }

Correct?

Richard
  • 7,037
  • 2
  • 23
  • 76

1 Answers1

2

The struct part is just a declaration, you can't execute any code there. malloc can only be executed at run-time. Meaning your struct should be

typedef struct {
    char* title;
    int year;
    int duration;
    int earnings;
} film;

Then later

film user[n];

for(int i=0; i<n; i++)
{
  char title [200];
  scanf("%s", title);  // scan to temporary buffer since we don't know length
  ...

  user[i]->title = malloc(strlen(title) + 1); // alloc just as much as is needed
}

Your free() code works.

Please note that this code is fairly naive; micro-managing memory like this might not be the best idea in real applications. Picking a fixed max string length instead and then making sure that the input doesn't exceed it might be a better plan, by using fgets instead of scanf.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Thank you for the answer! I have some questions, though. As you can probably tell, I'm still new to C, and I don't understand what you meant by micro-managing memory? Isn't fgets used to get the content from a file? Also, since I've already allocated memory for title at the size of 500 (typedef struct), why do I still allocate memory once again below at for loop? And, I've tried reading: http://www.learn-c.org/en/Dynamic_allocation and http://www.learn-c.org/en/Structures,....................................... – Richard May 31 '18 at 04:13
  • ......................... but I don't quite understand when we use "." and "->". I thought that -> is only used to access a member of a struct when said member is a pointer variable. However, from the Dynamic_allocation section on Learn C, it also used -> to access a member "int age" from the struct. Or is it possible to use both "." and "->" to access any struct members? – Richard May 31 '18 at 04:16
  • @WealthyPlayer It means that on the average PC/desktop application, it doesn't really matter if you allocate a 200 byte fixed string or if you allocate exactly "x" bytes. `fgets` is used to get characters from a _stream_, if you use `stdin` as input stream you can get characters from the console. It is a better function to use than `scanf` overall, but particularly so when reading strings. – Lundin May 31 '18 at 06:39
  • @WealthyPlayer The [500] is a typo in my answer, sorry about that! Fixed. – Lundin May 31 '18 at 06:39
  • @WealthyPlayer regarding `->` vs `.`, the former is merely a convenient way to access members when you have a pointer to a struct. It is more readable to write `ptr->title` than `(*ptr).title` but they are otherwise equivalent. – Lundin May 31 '18 at 06:41
  • Thank you for all the answers :-)! I've accepted your answer. One last question, though. As micro-managing memory is not really required nowadays, I assume for the most part, you should just allocate memory on stack unless the data is too large (I've read this: https://stackoverflow.com/questions/18217525/why-or-when-do-you-need-to-dynamically-allocate-memory-in-c), which may cause your memory not to have enough "single contiguous block" for the stack? – Richard Jun 01 '18 at 04:25
  • @WealthyPlayer Yeah on desktop applications, larger objects should be allocated on the heap. There's nothing wrong with allocating the strings in your example on the heap either, my remark merely meant that you shouldn't go lengths just to save some hundred bytes. – Lundin Jun 01 '18 at 06:29