Thread: Allocating dynamic memory to a string within a structure

  1. #1
    Registered User
    Join Date
    Dec 2018
    Posts
    13

    Allocating dynamic memory to a string within a structure

    Hi, I have the below code:

    Code:
    struct fact_entry
    {                               
      int n;
      long long int lli_fact;     
      char *str_fact;
    };
    
    int main (int argc, char *argv[])
    {
       int n;
       int i;
       struct fact_entry *fact_table;
       n = atoi (argv[1]);
       fact_table = (struct fact_entry *)malloc(n*sizeof(fact_table));
       for (i=0; i<n; i++) {
            if(i==0) {
                fact_table[i].n = 0;
                fact_table[i].lli_fact = 1;
                fact_table[i].str_fact = "1";
            }
            else {
                fact_table[i].n = i;
                fact_table[i].lli_fact = i*fact_table[i-1].lli_fact;
                /* the next line seems to be wrong*/
                fact_table[i].str_fact = (char *)malloc(log10(fact_table[i].lli_fact)); 
            }
        }
        for (i=0; i<n; i++) {
            printf("%d    %lld    %s\n", fact_table[i].n, fact_table[i].lli_fact, fact_table[i].str_fact);
        }
      return 0;
    }
    The program accepts an integer and return 3 columns, the 1st column is the array position, the 2nd column is the factorial and the 3d column is also the factorial but in string format.

    The 2 first columns are fine, it's the 3rd column that's failing, so I'm allocating memory the wrong way for the string within the struct. Could someone let me know what I'm doing wrong?

    Regards
    Last edited by Sergi; 04-03-2019 at 09:29 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well you need to create a string of some sort, not just allocate some space.

    > fact_table[i].str_fact = "1";
    A mixture of assigning string constants and malloc will be a real PITA later on.

    Code:
            if(i==0) {
                fact_table[i].n = 0;
                fact_table[i].lli_fact = 1;
            }
            else {
                fact_table[i].n = i;
                fact_table[i].lli_fact = i*fact_table[i-1].lli_fact;
            }
            fact_table[i].str_fact = malloc(20);  // max of a long long in decimal is 19 digits
            snprintf(fact_table[i].str_fact,20,"%lld",fact_table[i].lli_fact);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2018
    Posts
    13
    Quote Originally Posted by Salem View Post
    Well you need to create a string of some sort, not just allocate some space.

    > fact_table[i].str_fact = "1";
    A mixture of assigning string constants and malloc will be a real PITA later on.

    Code:
            if(i==0) {
                fact_table[i].n = 0;
                fact_table[i].lli_fact = 1;
            }
            else {
                fact_table[i].n = i;
                fact_table[i].lli_fact = i*fact_table[i-1].lli_fact;
            }
            fact_table[i].str_fact = malloc(20);  // max of a long long in decimal is 19 digits
            snprintf(fact_table[i].str_fact,20,"%lld",fact_table[i].lli_fact);

    Thanks Salem. The issue is, I'm already assigning the space with this line in my original code:
    Code:
           fact_table[i].str_fact = (char *)malloc(log10(fact_table[i].lli_fact));
    I've tried your solution as well but I'm still getting the same output, it looks like this:

    ./factor 19
    0 1 1
    1 1 P
    2 2
    3 6 ��
    4 24 �
    5 120

    6 720
    7 5040 P
    8 40320
    9 362880
    10 3628800 �
    11 39916800 39916800
    12 479001600 479001600
    13 6227020800 6227020800
    14 87178291200 87178291200
    15 1307674368000 1307674368000
    16 20922789888000 20922789888000
    17 355687428096000 355687428096000
    18 6402373705728000 6402373705728000

    So, the last columns seem to be fine, the problem is the first 10 lines, in which the 3rd column doesn't look fine, I'm still trying to figure out what could be the issue.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > fact_table = (struct fact_entry *)malloc(n*sizeof(fact_table));
    This is also wrong.

    It should be
    fact_table = malloc(n*sizeof(*fact_table));
    You weren't allocating anywhere near enough memory, leading to corrupt data.

    Also, stop casting malloc in your C programs.
    See the FAQ.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Dec 2018
    Posts
    13
    thanks Salem, it works fine now. I've found that nomenclature in many tutorials. Again, thanks for correcting that one.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Allocating memory to a structure
    By Layla_E in forum C Programming
    Replies: 2
    Last Post: 04-07-2018, 01:15 PM
  2. Replies: 4
    Last Post: 04-25-2010, 10:57 AM
  3. Allocating Memory for a Structure
    By surfxtc79 in forum C Programming
    Replies: 4
    Last Post: 06-05-2003, 11:40 AM
  4. dynamic memory allocating error
    By valhall in forum C Programming
    Replies: 2
    Last Post: 04-04-2003, 10:49 AM
  5. Allocating dynamic memory for structs
    By Nevyn in forum C Programming
    Replies: 4
    Last Post: 09-17-2001, 11:54 AM

Tags for this Thread