Thread: Doubt in structure

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    53

    Doubt in structure

    Consider the below program

    Code:
    struct str
    {
          char *p;
          int i;
    }t;
    
    main()
    {
        scanf("%s %d",t.p,&t.i);
        printf("%s",t.p);
    }
    the output is : Runtimer Error

    The reason is given that as we are trying to store the string at the address to which str(of t) points to. Since the pointer is not initialized it holds garbage value and so the reslult will be undefined. Hence the error.


    Then what about this

    Code:
    void main()
    {
             char *p;
             scanf("%s",p);
             printf("%s",p);
    }
    Here, though the pointer variable p is not initialized, it is accepting the input from the user and printing it without showing any error..


    May I know the reason in detail??
    Last edited by karthik537; 01-20-2009 at 08:36 PM.

  2. #2
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    That is undefined behaviour. It may work sometimes, it may not other times. I wouldn't depend it. Always allocate space for your variables!

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    The first one is probably trying to write to NULL, since it's a global.
    You got lucky in the second one. In that one it might not be NULL, and might point to somewhere in a valid memory page.

    Main must return int, not void.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Having a guess at this, in the first case *p is declared globally which means it will be initilaised to 0000, pointing to the first address in memory I think, possibly what is called a 'Null pointer', depends how it is defined internally, but I expect it is 0000.
    That is bound to generate a runtime error I think, segmentation violation??

    In the second case the pointer is declared as a local variable on the stack, which will not be automatically set to zero, it will be some pretty random value, depending, I think on what was previously on the stack.
    So.. either it just happens to write to a 'safe area' or what was previously on the stack was a pointer which pointed to a safe area.

    If you compiler it to produce the assembler code you might be able to work out what was on the stack, and where it was writing.
    Last edited by esbo; 01-20-2009 at 08:56 PM.

  5. #5
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Incidently when I run the second example on my machine the program crashed.

  6. #6
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    I compiled it as well, it segfaulted, which is what I expected.

    You need to include stdio.h
    You need to change your main function to return int.
    You need to allocate room in *p.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    53
    In the above structure code, in scanf statement are we trying to store the sting in the pointer or at the address pointed by the pointer.....

    If we declare

    Code:
    char *p;
              p = 12;
              *p = 20;
    it means that we are storing 12 in p at 2nd stmt and 20 is being stored at address pointed by the p i.e at address 12.

    So, I think in the scanf statement when we are trying to store the string in t.p, the address of the string will be stored in t.p... right?.....

    If not please tell me the correct one...in detail...please

  8. #8
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    I included stdio.h, but I didn't return int, none of my other progs reurn int and work fine.
    I changed it to return int and it still fails, it didn't say segfault, just
    "prog.exe has encountered a problem and needs to close".

  9. #9
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Anyway I compiled it to produce the assembler code, so I am sure you can see
    exactly what the problem is now <cough>


    Code:
    	.file	"null.c"
    	.def	___main;	.scl	2;	.type	32;	.endef
    	.section .rdata,"dr"
    LC0:
    	.ascii "%s\0"
    	.text
    .globl _main
    	.def	_main;	.scl	2;	.type	32;	.endef
    _main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$24, %esp
    	andl	$-16, %esp
    	movl	$0, %eax
    	addl	$15, %eax
    	addl	$15, %eax
    	shrl	$4, %eax
    	sall	$4, %eax
    	movl	%eax, -8(%ebp)
    	movl	-8(%ebp), %eax
    	call	__alloca
    	call	___main
    	movl	-4(%ebp), %eax
    	movl	%eax, 4(%esp)
    	movl	$LC0, (%esp)
    	call	_scanf
    	movl	-4(%ebp), %eax
    	movl	%eax, 4(%esp)
    	movl	$LC0, (%esp)
    	call	_printf
    	leave
    	ret
    	.def	_printf;	.scl	2;	.type	32;	.endef
    	.def	_scanf;	.scl	2;	.type	32;	.endef

  10. #10
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Just to make it easier I compiler a version which works
    Code:
    #include <stdio.h>
    int main()
    {
             char p[100];
             scanf("%s",p);
             printf("%s",p);
    }


    Assembler


    Code:
    	.file	"null.c"
    	.def	___main;	.scl	2;	.type	32;	.endef
    	.section .rdata,"dr"
    LC0:
    	.ascii "%s\0"
    	.text
    .globl _main
    	.def	_main;	.scl	2;	.type	32;	.endef
    _main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$152, %esp
    	andl	$-16, %esp
    	movl	$0, %eax
    	addl	$15, %eax
    	addl	$15, %eax
    	shrl	$4, %eax
    	sall	$4, %eax
    	movl	%eax, -124(%ebp)
    	movl	-124(%ebp), %eax
    	call	__alloca
    	call	___main
    	leal	-120(%ebp), %eax
    	movl	%eax, 4(%esp)
    	movl	$LC0, (%esp)
    	call	_scanf
    	leal	-120(%ebp), %eax
    	movl	%eax, 4(%esp)
    	movl	$LC0, (%esp)
    	call	_printf
    	leave
    	ret
    	.def	_printf;	.scl	2;	.type	32;	.endef
    	.def	_scanf;	.scl	2;	.type	32;	.endef

  11. #11
    Registered User
    Join Date
    Jan 2009
    Posts
    53
    In the above structure code, in scanf statement are we trying to store the sting in the pointer or at the address pointed by the pointer.....

    If we declare

    Code:
    char *p;
              p = 12;
              *p = 20;
    it means that we are storing 12 in p at 2nd stmt and 20 is being stored at address pointed by the p i.e at address 12.

    So, I think in the scanf statement when we are trying to store the string in t.p, the address of the string will be stored in t.p... right?.....

    If not please tell me the correct one...in detail...please

  12. #12
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Incidentl I am not sure how the numbers add up, looking at how the code has changed

    Code:
    subl	$152, %esp
    subl	$24, %esp#
    
    and
    movl	%eax, -8(%ebp)
    movl	%eax, -124(%ebp)

    I would expect to see a difference of 100 somewhere, of course 100 in hex is 64 so
    possibly 2 time 64 = 128??

    Note 128
    plus 24
    is = 152
    so I am not sure why it is twice 100, I guess it is down to word sizeor something like that.
    Last edited by esbo; 01-20-2009 at 09:49 PM.

  13. #13
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by karthik537 View Post
    In the above structure code, in scanf statement are we trying to store the sting in the pointer or at the address pointed by the pointer.....

    If we declare

    Code:
    char *p;
              p = 12;
              *p = 20;
    it means that we are storing 12 in p at 2nd stmt and 20 is being stored at address pointed by the p i.e at address 12.

    So, I think in the scanf statement when we are trying to store the string in t.p, the address of the string will be stored in t.p... right?.....

    If not please tell me the correct one...in detail...please
    I would say in the first p is pointing to 12, which would be a constant(?).
    In the second case the pointer is being set to the memory address 12, so whatever
    is at memory address 12 will be p, probably that wil be some fairly random data which
    will be treated as character codes if you try to print p. More likely the addess will be
    invalid (illegal value, out of bounds) and the program will produce a fault of some sort.

  14. #14
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by esbo View Post
    Just to make it easier I compiler a version which works
    Code:
    #include <stdio.h>
    int main()
    {
             char p[100];
             scanf("%s",p);
             printf("%s",p);
    }
    It won't work for strings over 99 non-whitespace characters long. Change it to:

    Code:
    #include <stdio.h>
    int main()
    {
             char p[100];
             scanf("%99s",p);
             printf("%s",p);
    }
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  15. #15
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    It's designed to crash if the string is too long

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. doubt regarding C structure in linux
    By Bargi in forum C Programming
    Replies: 2
    Last Post: 01-23-2007, 06:18 AM
  2. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  3. structure doubt...
    By incognito54 in forum C Programming
    Replies: 6
    Last Post: 04-21-2004, 11:54 AM
  4. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM
  5. C structure within structure problem, need help
    By Unregistered in forum C Programming
    Replies: 5
    Last Post: 11-30-2001, 05:48 PM