A puzzl about function

Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Aug 2004
Posts: 24
Reputation: XianBin is an unknown quantity at this point 
Solved Threads: 0
XianBin XianBin is offline Offline
Newbie Poster

A puzzl about function

 
0
  #1
Sep 19th, 2004
I don't how to description this puzzle, just like this:

  1. int *fun_num()
  2. {
  3. int b = 123;
  4. return &b;
  5. }
  6.  
  7. char *fun_char()
  8. {
  9. char *b = "123";
  10. return b;
  11. }
  12.  
  13. int main(int argc, char *argv[])
  14. {
  15. int *pfun;
  16. char *pchar;
  17. pfun = fun_num();
  18. pchar = fun_char();
  19.  
  20. cout << *pfun << endl;
  21. cout << *fun_num() << endl;
  22. cout << pchar << endl;
  23. cout << fun_char() << endl;
  24. }
//===============Result==============
4335768 // this is right to delete object "b"
123 // this is the return value
123 // why the object "b" isn't deleted? <---puzzle at here
123
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 185
Reputation: Stack Overflow is an unknown quantity at this point 
Solved Threads: 4
Stack Overflow's Avatar
Stack Overflow Stack Overflow is offline Offline
C Programmer

Re: A puzzl about function

 
0
  #2
Sep 19th, 2004
Greeting XianBin,

Pointers can be somewhat confusing, but let's see if we can go through this code one step at a time. It may help the understanding of how it works, and how useful these techniques can be.

Let's disect the functions first:

int *fun_num() {
	int b = 123;
	return &b;
}
» What this does, is it creates an integer b, and returns the memory address of this variable. That's why the function's return-type is "int *".

char *fun_char() {
	char *b = "123";
	return b;
}
» This does almost the same thing, as it creates a variable "char *" and returns it. Not the memory address since an array name is a pointer. If you were to send the memory address, then you would need to change the return-type to "char **". Oh, and the b variable would need a real block of memory, since right now it is only staticly created.

Now moving inside main, lets take a look at our routines:
int *pfun;
char *pchar;
» These are your local variables. One is a pointer to an integer, and the other, a char array [or pointer]. The "char *" array only needs data, though the integer pointer needs the memory address to look at the data we send.

  1. pfun = fun_num();
» Ah, the messy stuff. Well, this is quite simple, so I'll explain it as simple as possible. This contains pfun. If you may know, pfun is not the actual data itself, its the address. Remember in fun_num() we returned the address of our local variable b, well that address will be sent directly to pfun. Now in order to read the data passed through the address we would be smart to use the unary operator "*".

The reason you need the unary (*) operator, is because we sent the memory address to our function. Let me clarify. If a variable contains data here (d) and its memory address is here (m), I would need to get to (m)->(d) to access the data from the address sent. Likewise, the * operator allows me to read the data from the address. Using the * will point to the data instead of looking or modifying the address. So overall, pfun is our address, and *pfun is our data from our address.

  1. pchar = fun_char();
» This is somewhat the same, but different. Remember that this will only contain the data without touching the address. This syntax is correct since with the previous line of code we sent address to address, but now we are sending data to data.

  1. cout << *pfun << endl;
» Ah, we are reading our data here.

  1. cout << *fun_num() << endl;
» Same address, doesn't matter where we call it. Reading the same data as *pfun.

  1. cout << pchar << endl;
» Remember, pchar is now reading whatever fun_char() holds. They aren't exactly linked like pointers and addresses, but you sent the data from our function to our variable. As long as that occurs, the data will still be there. It can't be delete either, since b isn't exactly our property to touch in fun_char(). It's dynamically out there somewhere.

  1. cout << fun_char() << endl;
» Same data, but not same address. If this function were to have allocated a memory block we could possibly send the address anywhere we want.

Conclusion
Though it isn't recommended to do a statement like so:
char *b = "123";
I don't want to be harsh or anything telling you it isn't safe or anything like that. Using malloc() may save you some headache down the line, but I'll explain that when you're ready or have learned it and/or have further questions about it.

I hope this information has helped you in great detail. If you have any further questions, please feel free to ask.


- Stack Overflow
Following the rules will ensure you get a prompt answer to your question. If posting code, please include BB [code][/code] tags. Your question may have been asked before, try the search facility.

IRC
Channel: irc.daniweb.com
Room: #c, #shell
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,363
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 242
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: A puzzl about function

 
0
  #3
Sep 19th, 2004
Originally Posted by Stack Overflow
Now moving inside main, lets take a look at our routines:
int *pfun;
  char *pchar;
» These are your local variables. One is a pointer to an integer, and the other, a char array [or pointer].
An array is not a pointer. The fewer times folks are told this, the better.
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,730
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 737
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: A puzzl about function

 
0
  #4
Sep 19th, 2004
>Though it isn't recommended to do a statement like so
Right answer, wrong reason. Assigning a string literal to a pointer to char is a deprecated feature in C++. The correct way would be:
  1. const char *b = "123";
>why the object "b" isn't deleted? <---puzzle at here
Not to take away from Stack Overflow's answer, but I can summarize. The memory for b is released, but the memory for what b points to is not. The reason is that string literals have static storage duration. In other words, the memory exists and can be accessed (but never modified) for the duration of the program as long as you have a pointer to it.
Reply With Quote Quick reply to this message  
Join Date: Aug 2004
Posts: 24
Reputation: XianBin is an unknown quantity at this point 
Solved Threads: 0
XianBin XianBin is offline Offline
Newbie Poster

Re: A puzzl about function

 
0
  #5
Sep 27th, 2004
a net friend suggested me to try to make the assemble file and reading it,so I try to do it,then I konw clearly what the promgram does.
I try to introduce it, I hope everyone to understand what I said, because my English so poor.


==================The problem description==================
  1. [....]
  2. _TEXT segment byte public 'CODE'
  3. _fun_num proc near
  4. [...]
  5. mov word ptr [bp-2],123 ; The Number '123' is saved in the [bp-2] addr.
  6.  
  7. lea ax,word ptr [bp-2] ; Address is saved in AX reg.
  8. [...]
  9. ret
  10. _fun_num endp
  11. _TEXT ends
  12.  
  13. [...]
  14.  
  15. _TEXT segment byte public 'CODE'
  16. _fun_char proc near
  17. push si ; Now the SP pointer is pointing to the Number '123' 's addr.
  18. mov si,offset DGROUP:s@ ; Will Load the "123" strings.
  19. mov ax,si ; Loading the "123" strings. It overwrited the '123' numbers.This is why the result is unknown.
  20. [...]
  21. ret
  22. _fun_char endp
  23. _TEXT ends
  24.  
  25. _TEXT segment byte public 'CODE'
  26. _main proc near
  27. push bp
  28. mov bp,sp
  29. push si
  30. push di
  31.  
  32. call near ptr _fun_num
  33. mov si,ax
  34.  
  35. call near ptr _fun_char
  36. mov di,ax
  37. [...]
  38.  

==============Writing By C Code==============
  1. #include<stdio.h>
  2.  
  3. int *fun_num()
  4. {
  5. int b = 123;
  6. return &b;
  7. }
  8.  
  9. char *fun_char()
  10. {
  11. char *b = "123";
  12. return b;
  13. }
  14.  
  15. int main(int argc, char *argv[])
  16. {
  17. int *pfun;
  18. char *pchar;
  19. pfun = fun_num();
  20. pchar = fun_char();
  21.  
  22. printf("pfun=%d\n",*pfun);
  23. printf("fun_num()=%d\n",*fun_num());
  24. printf("pchar=%s\n",*pchar);
  25. printf("fun_char()=%s\n",*fun_char());
  26.  
  27. return 0;
  28. }
----------------Assemble Code----------------
  1. ifndef ??version
  2. ?debug macro
  3. endm
  4. endif
  5. ?debug S "function.c"
  6. _TEXT segment byte public 'CODE'
  7. DGROUP group _DATA,_BSS
  8. assume cs:_TEXT,ds:DGROUP,ss:DGROUP
  9. _TEXT ends
  10. _DATA segment word public 'DATA'
  11. d@ label byte
  12. d@w label word
  13. _DATA ends
  14. _BSS segment word public 'BSS'
  15. b@ label byte
  16. b@w label word
  17. ?debug C E99DBA3B310A66756E6374696F6E2E63
  18. _BSS ends
  19. _TEXT segment byte public 'CODE'
  20. ; ?debug L 1
  21. _fun_num proc near
  22. push bp
  23. mov bp,sp
  24. sub sp,2
  25. ; ?debug L 3
  26. mov word ptr [bp-2],123
  27. ; ?debug L 4
  28. lea ax,word ptr [bp-2]
  29. jmp short @1
  30. @1:
  31. ; ?debug L 5
  32. mov sp,bp
  33. pop bp
  34. ret
  35. _fun_num endp
  36. _TEXT ends
  37. _DATA segment word public 'DATA'
  38. _DATA ends
  39. _TEXT segment byte public 'CODE'
  40. ; ?debug L 7
  41. _fun_char proc near
  42. push si
  43. ; ?debug L 9
  44. mov si,offset DGROUP:s@
  45. ; ?debug L 10
  46. mov ax,si
  47. jmp short @2
  48. @2:
  49. ; ?debug L 11
  50. pop si
  51. ret
  52. _fun_char endp
  53. _TEXT ends
  54. _DATA segment word public 'DATA'
  55. _DATA ends
  56. _TEXT segment byte public 'CODE'
  57. ; ?debug L 13
  58. _main proc near
  59. push bp
  60. mov bp,sp
  61. push si
  62. push di
  63. ; ?debug L 17
  64. call near ptr _fun_num
  65. mov si,ax
  66. ; ?debug L 18
  67. call near ptr _fun_char
  68. mov di,ax
  69. ; ?debug L 20
  70. push word ptr [si]
  71. mov ax,offset DGROUP:s@+4
  72. push ax
  73. call near ptr _printf
  74. pop cx
  75. pop cx
  76. ; ?debug L 21
  77. call near ptr _fun_num
  78. mov bx,ax
  79. push word ptr [bx]
  80. mov ax,offset DGROUP:s@+13
  81. push ax
  82. call near ptr _printf
  83. pop cx
  84. pop cx
  85. ; ?debug L 22
  86. mov al,byte ptr [di]
  87. cbw
  88. push ax
  89. mov ax,offset DGROUP:s@+27
  90. push ax
  91. call near ptr _printf
  92. pop cx
  93. pop cx
  94. ; ?debug L 23
  95. call near ptr _fun_char
  96. mov bx,ax
  97. mov al,byte ptr [bx]
  98. cbw
  99. push ax
  100. mov ax,offset DGROUP:s@+37
  101. push ax
  102. call near ptr _printf
  103. pop cx
  104. pop cx
  105. ; ?debug L 25
  106. xor ax,ax
  107. jmp short @3
  108. @3:
  109. ; ?debug L 26
  110. pop di
  111. pop si
  112. pop bp
  113. ret
  114. _main endp
  115. _TEXT ends
  116. ?debug C E9
  117. _DATA segment word public 'DATA'
  118. s@ label byte
  119. db 49
  120. db 50
  121. db 51
  122. db 0
  123. db 112
  124. db 102
  125. db 117
  126. db 110
  127. db 61
  128. db 37
  129. db 100
  130. db 10
  131. db 0
  132. db 102
  133. db 117
  134. db 110
  135. db 95
  136. db 110
  137. db 117
  138. db 109
  139. db 40
  140. db 41
  141. db 61
  142. db 37
  143. db 100
  144. db 10
  145. db 0
  146. db 112
  147. db 99
  148. db 104
  149. db 97
  150. db 114
  151. db 61
  152. db 37
  153. db 115
  154. db 10
  155. db 0
  156. db 102
  157. db 117
  158. db 110
  159. db 95
  160. db 99
  161. db 104
  162. db 97
  163. db 114
  164. db 40
  165. db 41
  166. db 61
  167. db 37
  168. db 115
  169. db 10
  170. db 0
  171. _DATA ends
  172. _TEXT segment byte public 'CODE'
  173. extrn _printf:near
  174. _TEXT ends
  175. public _fun_char
  176. public _fun_num
  177. public _main
  178. end
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC