Skip to content
Advertisement

Data gets distorted which is printed in loop

Facing issue when printing the data that is updated in malloc. In the below code am creating a string Test.DataType_1.Tag_1 …. Test.DataType_1.Tag_20 in create_tags() function, when the data is updated properly and printed i create_tags() function it prints properly but if printed in main() function in for loop data is distorted.

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

#define NUM_OF_TAGS            (20)
#define NUM_DATA_TYPES         (01)

#define MAX_SUBSCRIPTION        (1)
#define MAX_MONITORED_ITEMS     (2)
#define MAX_ITEMS_TO_CREATE     (20)
   
typedef struct
{
    char nodeID[50];
}TAG_NAME;

typedef struct
{
    int32_t group_id;
    TAG_NAME *tag;
}GROUP;


int32_t max_subscription;
int32_t max_monitored_item;
int32_t max_item_to_create;

void create_tags(GROUP *node)
{
    char t_node[50];
    char r_node[50];
    memset(r_node, 0, sizeof(r_node));
    memset(t_node, 0, sizeof(t_node));

    for(int i = 1; i <= NUM_OF_TAGS; i++)
    {
        sprintf(t_node, "Test.DataType_1.Tag_%d", i);
        strcat(r_node, t_node);
        strcpy(node->tag[i].nodeID, r_node);
        printf("%sn", node->tag[i].nodeID);
        memset(t_node, 0, sizeof(t_node));
        memset(r_node, 0, sizeof(r_node));
    }
}


int main(void)
{
    max_subscription = MAX_SUBSCRIPTION;
    max_monitored_item = MAX_MONITORED_ITEMS;
    max_item_to_create = MAX_ITEMS_TO_CREATE;

    GROUP *group = NULL;
    /* Grouping Nodes */
    group = malloc(sizeof(GROUP) * max_subscription * max_monitored_item);
    for(int j = 0; j < max_subscription * max_monitored_item; j++)
    {
        group[j].tag  = malloc(sizeof(GROUP) * max_item_to_create);
        memset(group[j].tag, 0, sizeof(GROUP) * max_item_to_create);
        printf("########## Set %d: Start ###########n", j);
        group[j].group_id = j;
        create_tags(&group[j]);
        printf("########## End %d: Start ###########n", j);
        printf("n");
    }

    int32_t count = 0;


    for(int32_t i = 0; i < max_subscription; i++)
    {
        for(int32_t j = 0; j < max_monitored_item; j++)
        {
            printf("============= Start: %d ===============n", count );
            for (int32_t k = 0; k < max_item_to_create; k++)
            {
                printf("%sn", group[count].tag[k].nodeID);
            }
            printf("============= End: %d ===============n", count);
            count++;
        }
    }

}

The output of the code is follows, when i print the data inside create_tags() function, the data populated is correctly printed here am printing the same data twice. But when i print the same in loops it get distorted in printf("%sn", group[count].tag[k].nodeID);

########## Set 0: Start ###########
Test.DataType_1.Tag_1
Test.DataType_1.Tag_2
Test.DataType_1.Tag_3
Test.DataType_1.Tag_4
Test.DataType_1.Tag_5
Test.DataType_1.Tag_6
Test.DataType_1.Tag_7
Test.DataType_1.Tag_8
Test.DataType_1.Tag_9
Test.DataType_1.Tag_10
Test.DataType_1.Tag_11
Test.DataType_1.Tag_12
Test.DataType_1.Tag_13
Test.DataType_1.Tag_14
Test.DataType_1.Tag_15
Test.DataType_1.Tag_16
Test.DataType_1.Tag_17
Test.DataType_1.Tag_18
Test.DataType_1.Tag_19
Test.DataType_1.Tag_20
########## End 0: Start ###########

########## Set 1: Start ###########
Test.DataType_1.Tag_1
Test.DataType_1.Tag_2
Test.DataType_1.Tag_3
Test.DataType_1.Tag_4
Test.DataType_1.Tag_5
Test.DataType_1.Tag_6
Test.DataType_1.Tag_7
Test.DataType_1.Tag_8
Test.DataType_1.Tag_9
Test.DataType_1.Tag_10
Test.DataType_1.Tag_11
Test.DataType_1.Tag_12
Test.DataType_1.Tag_13
Test.DataType_1.Tag_14
Test.DataType_1.Tag_15
Test.DataType_1.Tag_16
Test.DataType_1.Tag_17
Test.DataType_1.Tag_18
Test.DataType_1.Tag_19
Test.DataType_1.Tag_20
########## End 1: Start ###########

============= Start: 0 ===============

Test.DataType_1.Tag_1
Test.DataType_1.Tag_2
Test.DataType_1.Tag_3
Test.DataType_1.Tag_4
Test.DataType_1.Tag_5
Test.DataType_1.Tag_6
1.Tag_6
 ===============

Test.DataType_1.Tag_8
Test.DataType_1.Tag_9
Test.DataType_1.Tag_10
Test.DataType_1.Tag_11
Test.DataType_1.Tag_12
Test.DataType_1.Tag_13
Test.DataType_1.Tag_14
Test.DataType_1.Tag_15
Test.DataType_1.Tag_16
Test.DataType_1.Tag_17
Test.DataType_1.Tag_18
Test.DataType_1.Tag_19
============= End: 0 ===============

============= Start: 1 ===============

Test.DataType_1.Tag_1
Test.DataType_1.Tag_2
Test.DataType_1.Tag_3
Test.DataType_1.Tag_4
Test.DataType_1.Tag_5
Test.DataType_1.Tag_6
Test.DataType_1.Tag_7
Test.DataType_1.Tag_8
Test.DataType_1.Tag_9
Test.DataType_1.Tag_10
Test.DataType_1.Tag_11
Test.DataType_1.Tag_12
Test.DataType_1.Tag_13
Test.DataType_1.Tag_14
Test.DataType_1.Tag_15
Test.DataType_1.Tag_16
Test.DataType_1.Tag_17
Test.DataType_1.Tag_18
Test.DataType_1.Tag_19
============= End: 1 ===============

Any hint as to why this is happening will be helpful.

Advertisement

Answer

In your main function, you allocate both the group array, and the tag array within it, with an element size of sizeof(GROUP). In addition, you use that same size when zeroing out the tag array:

group = malloc(sizeof(GROUP) * max_subscription * max_monitored_item);

group[j].tag  = malloc(sizeof(GROUP) * max_item_to_create);
memset(group[j].tag, 0, sizeof(GROUP) * max_item_to_create);

Since GROUP consists of an integer and pointer, it’s almost certainly going to be smaller that the 50-byte TAG_NAME. That would mean you don’t allocate enough space for it, probably leading to buffer overruns in the memory arena later on, where your code assumes it has enough space.

You should use sizeof(TAG_NAME) when allocating (and zeroing) the tag array. But, given you want to zero-initialise it, you may want to use calloc instead of the malloc/memset combo:

group[j].tag  = calloc(max_item_to_create, sizeof(TAG_NAME));
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement