0

I want to know, how the value is printed for the below items. because i set the structure variable one to 0 using memset. but this variable is assigned in mainst.subst using init() method.

printf("\n %d",mainst.subst.t1); printf("\n %d",mainst.subst.t2);

Please kindly let me any one know why its print like that.

Source Code:

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

typedef struct one *oneptr;

struct one
{
        char t1;
        char t2;
        char *path;
};
typedef struct one one_st;

struct char_ar
{
        int a;
        char b;
        one_st subst;
}mainst;

void init(oneptr cp)
{
        mainst.a=10;
        mainst.b='u';
        mainst.subst=*cp;
}

void main()
{
        oneptr ptr;
        struct one o;
        o.t1='t';
        o.t2='u';
        o.path = malloc(10);
        strcpy(o.path,"HI");

        init( &o);

        ptr = &o;
        free(ptr->path);
        ptr->path=(char *)NULL;

        memset ((char *)ptr, 0, sizeof(one_st));

        printf("\n %d",mainst.subst.t1);
        printf("\n %d",mainst.subst.t2);
        printf("\n %s",mainst.subst.path);

}
user2815465
  • 91
  • 1
  • 1
  • 3
  • What was printed? And what did you *expect* to be printed? – Roddy Aug 18 '15 at 10:46
  • two notable problems: 1) mainst.subst=*cp; will NOT copy the whole cp struct. suggest: memcpy(mainst.subst, cp, sizeof( struct one); 2) always check (!=NULL) the returned value from malloc() to assure the operation was successful – user3629249 Aug 18 '15 at 13:54

2 Answers2

0

You are calling memset on o, which is a stack allocated structure. But you are printing the contents of mainst, which is a different value in your data segment. So the call to memset has no effect on your program.

user3188445
  • 4,062
  • 16
  • 26
  • Thanks for your reply. But i assigned `mainst.subst=*cp;` where `cp` has the address of structure variable `o`. While accessing the value `mainst.subst` which points to structure variable `o`. is it right? Correct me if i wrong. – user2815465 Aug 18 '15 at 07:16
  • @user2815465 That just copied the contents of `o` into `mainst.subst`. But `mainst.subst` is not a pointer, it's a structure embedded in `mainst` which is in your heap. Totally different memory from `o`. – user3188445 Aug 18 '15 at 07:19
0

When you execute mainst.subst=*cp; , it sets mainst.subst.path to point to the same place as ptr->path, i.e. the block that you malloc'd. So you have one memory block with two pointers pointing to it.

But then you have:

free(ptr->path);
// ...
printf("\n %s",mainst.subst.path);

ptr->path and mainst.subst.path both point to the same block which you allocated via malloc. You free that block, and then you pass the address of that block to printf. Using the address of a freed block causes undefined behaviour.


Note that your memset did not even try to write into the freed block. You scrubbed all over o but that has no effect on memory being pointed to by a member of o because you did not follow the pointer.

Perhaps what you meant to do was something like:

ptr = &o;
memset(ptr->path, 0, 10);
free(ptr->path);

however it would still cause undefined behaviour to use mainst.subst.path because it still points to a freed block.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365