0

Hey) I have struct with members as pointers, And I want to create struct variable as pointer too.

I hope efficiency in malloc() that we do not store struct var in the Stack and keep executable file "a.out" byte less in HDD. Only Dynamic memory use. Please check, is this program can be more effective way written? Is my vision on memory correct and effective? Thx!

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

struct pbookInfo { // define the struct pbookInfo here
    char * title;
    char * author;
};

int main(){

/* vars */

    char esc = 'X'; // exit point
    int i; // for loop counter

    // struct with member as * pointers, and struct var as * pointer
    struct pbookInfo * books; // struct var pointer

/* code - memory allocation */
    books = (struct pbookInfo *)malloc(sizeof(struct pbookInfo)); // memory for struct var
    // if memory fail
    if(books == 0){
        puts("\nmallocate fail - memory not enough");
        exit(1);
    }
    books -> title = (char *)malloc(10); // memory for member 'title'
    books -> author = (char *)malloc(5); // memory for member 'autor'
    // if memory fail
    if(books->title == 0 || books -> author == 0){
        puts("\nmallocate fail - memory not enough");
        exit(1);
    }

/* some expression mock, for example: */
    strcpy(books->title,"Storenth");
    strcpy(books->author,"Kira");

    // mock

/* allocated memory free */
    free(books->title);
    free(books->author);
    free(books);
    puts("All memory free!");

// exit point
    puts("\nexit point:");
    scanf(" %c", &esc);
    return 0;
}
storenth
  • 967
  • 11
  • 18
  • declare `struct pbookInfo { // define the struct pbookInfo here char title[10]; char author[5]; };` for starters instead of mallocing a fixed size for title & author fields. Or compute size first and malloc. – Jean-François Fabre Aug 27 '17 at 13:23
  • Be consistent with spacing. There shouldn't ever be spaces around either the dot `.` operator or the arrow `->` operator. They bind very tightly. – Jonathan Leffler Aug 27 '17 at 14:31

3 Answers3

1

Declaring a variable on the Stack does not affect the size of the executable (a.out) file, unless you are declaring constants or string constants. Declaring variables on the stack is faster compared to using malloc(). Dynamic memory allocation is used when large amount of memory needs to be allocated and that memory needs to persist across function calls.

1

In general unless you need to keep the data persistent (i.e. keep it "alive" after you return from a function) it is not necessary to use malloc(). You really only need it if you have to manipulate copies of data which are of variable size or sometimes for thread safe functions.

malloc() is not an efficient way to grab memory for single temporary variables and also comes with the overhead of a call to free() to undo it before you return. So it's slow.

Also note that it's very easy to forget to free() allocated memory and it's why memory leaks happen. So introducing malloc() for no good reason is just adding more potential for bugs.

Simply declaring local variables is practically no overhead, as the space is allocated automatically by the function when called, and all space for local variables gets allocated in one single operation (just reserving some space on the stack).

Freeing local variables requires no code (a huge benefit) and has zero cost, because it simply gets released as part of the single operation to restore the stack as part of the function return.

Using malloc() and free() will require more space in the executable. Reserving space on the stack for local variables is (typically) zero overhead in code size.

0

First please read why we shouldn't cast return value of malloc.

I hope efficiency in malloc() that we do not store struct var in the Stack and keep executable file "a.out" byte less in HDD. Only Dynamic memory use.

That's not true. Automatic arrays are way more efficient then the dynamic ones. They are also easier to use and less error-prone.

You should use dynamic allocation only if you have to. Like you dont know size of input data (There is still way to use VLA since ).

Also changing storages automatic & dynamic won't affect size of executable.


Allocating space for arrays should look like (adapt to size of data you want to store in)

books -> title = malloc(strlen("Storenth") + 1); // 1 for null terminating byte
books -> author = malloc(strlen("Kira") + 1);

strcpy(books->title,"Storenth");
strcpy(books->author,"Kira");

Also take a moment and think about famous citation

Premature optimization is the root of all evil -- DonaldKnuth

kocica
  • 6,412
  • 2
  • 14
  • 35
  • `strcpy(books->title,"Storenth");` leads to UB as allocated memory is too small. – chux - Reinstate Monica Aug 27 '17 at 13:34
  • What is automatic arrays? – storenth Aug 27 '17 at 13:40
  • Array declared on stack, such as `char array[10];`. [Here(click)](https://stackoverflow.com/a/35445125/8254699) its pretty nice explained. – kocica Aug 27 '17 at 13:46
  • Note that you could also use, e.g., `books -> title = malloc(sizeof "Storenth");`. This avoids a function call, and the `sizeof` expression is evaluated at compile time (in most cases). Also, space for the null terminator is automatically included in this. – ad absurdum Aug 27 '17 at 14:27
  • Interesting, i didnt know that. Thank you. – kocica Aug 27 '17 at 14:35
  • 1
    `First please read why we shouldn't cast return value of malloc.` stop linking this outdated ancient advice. – 0___________ Aug 27 '17 at 14:36
  • Why ? It seems useful for me. Could you explain it? – kocica Aug 27 '17 at 14:40
  • @FilipKočica-- on using `sizeof "Storenth"`: note that a string literal has type `char []`, not `char *`, as is often believed (and not `const char []` or `const char *`, either). This means that a string literal decays to a pointer in most expressions, but not in `sizeof` expressions, where a string literal still has an array type. – ad absurdum Aug 27 '17 at 15:34