Solved

Confusing output

Posted on 2004-03-31
18
250 Views
Last Modified: 2010-04-15
Hi ,
   I am stuck at a simple piece of C code as I cannot explain its output. Here it goes...

#include<stdio.h>
void main()
{
 int i="Hello",j;
 char * a;
 a="World";
 j=a;
 printf("i=%d  j=%d",i,j);
}

Output in both the cases is 170.
I am looking forward to a detailed explanation/discussion on this.

Thanks in advance,
Avik.
0
Comment
Question by:Avik77
  • 7
  • 6
  • 2
  • +3
18 Comments
 
LVL 2

Author Comment

by:Avik77
ID: 10725744
Sorry,
 output was i=170 j=176
0
 
LVL 4

Expert Comment

by:booki
ID: 10725794
Avik77,

>> int i="Hello",j;

i gets address of const string "Hello"

>> a="World";

a gets address of const string "World"

>> j=a;

j gets address of const string "World"

>> printf("i=%d  j=%d",i,j);

output:

i=4342276 j=4341932

i'm not getting the same results as you...

b.

0
 
LVL 4

Expert Comment

by:booki
ID: 10725887
Avik77,

String literals in expressions are converted to pointers const strings.

For a detailed discussion see:
http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_20917922.html

b.
0
 
LVL 45

Expert Comment

by:Kdo
ID: 10725905
Hi booki,

"Hello" and "World" should be string in consecutive locations in the literals block.  strlen("Hello") is 6.  The values that the poster is displaying are 70 and 76 - a difference of 6 cells.  (It would appear that your strings are located in different blocks.  Interesting....)


The poster may be using 16-bit integers and therefore getting only the lower 16 bits of the address.  


Kent
0
 
LVL 4

Expert Comment

by:booki
ID: 10725938
Avik77,

>> output was i=170 j=176

The difference of 6 is because "Hello\0" is 6 char long and is followed immediately in memory by "World\0".. However 170 and 176 seem to be quite low for valid pointer values...

I tried it on my linux box and still got similar results as my first post. ie:

i = 134513680  j = 134513686

// *note i-j == 6

What compiler/platform are you using?

b.
0
 
LVL 4

Expert Comment

by:booki
ID: 10725958
Kdo,

>> (It would appear that your strings are located in different blocks.  Interesting....)

Yup, the first run was with VC++7 on xp.. go figure.

b.
0
 
LVL 14

Expert Comment

by:wayside
ID: 10726038
I tried this on VC++.Net 2002, and got a compile error:

error C2440: 'initializing' : cannot convert from 'const char [6]' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast

That's compiling from the command line with the default warning level.

Oh well, if I cast I get:

i=4227552  j=4227560

I don't believe there is any requirement that to two static strings be consecutive in memory. In this case it looks like the linker is putting the strings on an 8 byte boundary.

0
 
LVL 2

Author Comment

by:Avik77
ID: 10726296
I am trying in Turbo C++ v3.0. I agree to that of Booki because I have modified the program like this

#include<stdio.h>
void main()
{
 int i="Hello",j,k;
 char * a,*b;
 clrscr();
 a="";
 b="Thanks";
 j=a;k=b;
 printf("i=%d  j=%d  k=%d",i,j,k);
 getch();
}
and output is i=170  j=176  k=177
But still I am not getting why every first string gets always initialised to an integer with a value of 170 and then others follow as sequentially and also why different platforms are behaving so differently to this.

Avik.
0
 
LVL 17

Expert Comment

by:mokule
ID: 10726459
It's because Turbo C++ v3.0 generates 16 bit code. The addresses 170 176 and so on relative to the segment where resides data.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 2

Author Comment

by:Avik77
ID: 10726586
Ok, but is the offset 170 a mandatory for initializing a string literal. If yes, then what *type* of data segment is this, can't we modify the value there. According to Booki it is a read only memory then why should any string literal be every time get initialized to an offset of 170 relative to the data segment. What may be stored from offset 0 to 169. Moreover why should a offset value  be printed rather than an address value. I have changed the int to unsigned int and the '%d' to '%u' but still the same.
0
 
LVL 4

Expert Comment

by:booki
ID: 10726629
Avik77,

>> But still I am not getting why every first string gets always initialised to an integer
>> with a value of 170 and then others follow as sequentially

170 is simply the location of where that first string is stored.  170 just happens to be the first available slot in this particular case. it is not a special number.

int i = "Hello";

is not good practice but what is happening here is that a string literal ("Hello") is used to initialize the integer i.  in the context of an expression, a string literal is converted by the compiler to a pointer to/address of/location of the string literal.in memory which in this case happens to be 170.  the others follow immediately after because.. well its a good place to put them, side by side.  it's compact.

>> and also why different platforms are behaving so differently to this.

the other platforms/compilers are not behaving differently.  the same thing is happening. the only difference is that you're generating 16 bit code as mokule pointed out, so the values appear different but the same thing is happening.

the first results i posted seemed scattered because your sample code was surrounded by a whole lot of other code that i was working on... =)..

b.
0
 
LVL 2

Author Comment

by:Avik77
ID: 10726757
Hi Booki,
       seems my 3rd post came before ur 5th post.
Avik.
0
 
LVL 4

Accepted Solution

by:
booki earned 40 total points
ID: 10727340
Avik77,

>> why should any string literal be every time get initialized to an offset of 170 relative to the data segment

It's likely that offset 170 is the first available slot.  Perhaps looking into the 16-bit NE file format (the binary file format) may shed more light on what gets placed where and why.

>> What may be stored from offset 0 to 169.

hmmm... not sure but if i had to guess.. i'd say other data.. possibly from statically linked libs (eg. C runtime)

>> Moreover why should a offset value  be printed rather than an address value.

in real mode/segmented memory model that's what you get.. offsets.  in protected mode (paged memory) you get a flat address space.

>>  I have changed the int to unsigned int and the '%d' to '%u' but still the same.

of course, were you expecting something else?

>> According to Booki it is a read only memory

actually this is not guaranteed by the ansi standard.. though many compilers do this it is not required.

b.
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 10730614
Are you asking why it is starting from 170 whenever you run or is it something else!?
0
 
LVL 2

Author Comment

by:Avik77
ID: 10733688
Just to get some different results, I tried. Please correct me if I have some misconceptions here.

#include<stdio.h>
void main()
{
 int * i="Hello",*j,*k,*l;
 char * a;
 clrscr();
 a="";
 j=a;k=&j,l=&a;
 printf("i=%u  j=%u  k=%u l=%u",i,j,k,l);
 getch();
}
output is i=170 j=176 k=65520 l=65514

if i and j are offset values what is k then. Although i and j points to memory address of the string literals "Hello" and "" and k points to address of j and l points to the address of a. How can we account for this. Please clear my misconception. I have little knowledge about this.

Avik.
0
 
LVL 4

Expert Comment

by:booki
ID: 10733943
Avik77,

K and L hold offsets for the location of J and A, both of which are on the stack.  The stack grows down from high to low so the 'bottom' of the stack would be at offset 65535 (the maximum 16 bit value).

Notice that:
    - both J and A are very close to the bottom of the stack
    - J is closer to the bottom than A.
    - J and A are 6 bytes apart.  since one pointer is only 2 bytes there is a gap
      of 4 bytes in between.  just enough room for K and L.  the compiler has placed
      your variables on the stack in declaration order.

b.
0
 
LVL 14

Assisted Solution

by:wayside
wayside earned 20 total points
ID: 10734079
There is a difference between the address of a pointer, and the contents of the pointer.

The contents of i and j are pointers to static strings, which have values of 170 and 176.

k contains the address of the local variable j - iow, the contents of j are stored at memory address 65520. Memory location 65520 contains 176, which is a pointer to the static string "".

similarly, l contains the address of a.

Think of each memory location as  a tiny container. This container has two properties  - its address, and its contents. The contents can be a numerical value which represents a number (i.e., 6) or a numerical value which represents another memory location.

For example:

the variable i has address of 65522 (let's say) and contents of 170 (address of "Hello")
the variable j has address of 65520 and contents of 176 (same as a, as j was assigned a's value
the variable k has address of 65518 (let's say) and contents of 65520 (which is j's memory address)
the variable l has address of 65516 (let's say) and contents of 65514 (which is a's address)
the variable a has address of 65514 and contents of 176 (address of "")

address 176 contains the first character of the static string ""
address 170 contains the first character of the static string "Hello"
address 171 (likely) contains the second character of "Hello"
etc.

Does this help?
0
 
LVL 2

Author Comment

by:Avik77
ID: 10734123

So they are offsets to the stack segment and the location of the string literals are the offset to the data segment. Since stack grows from high to low we get large values of offsets, but for const string literals it starts from the top. Are they the same segment i.e. SS=DS. I have this much to know .

Avik.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now