472-474.html
来自「linux-unix130.linux.and.unix.ebooks130 l」· HTML 代码 · 共 146 行
HTML
146 行
<HTML>
<HEAD>
<TITLE>Linux Unleashed, Third Edition:Programming in C</TITLE>
<SCRIPT>
<!--
function displayWindow(url, width, height) {
var Win = window.open(url,"displayWindow",'width=' + width +
',height=' + height + ',resizable=1,scrollbars=yes');
}
//-->
</SCRIPT>
</HEAD>
-->
<!--ISBN=0672313723//-->
<!--TITLE=Linux Unleashed, Third Edition//-->
<!--AUTHOR=Tim Parker//-->
<!--PUBLISHER=Macmillan Computer Publishing//-->
<!--IMPRINT=Sams//-->
<!--CHAPTER=26//-->
<!--PAGES=472-474//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="468-472.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="474-478.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P>By listing the file, we can see that the place where we want to set the breakpoint is line 24. Now, to set the breakpoint, enter the following command at the <TT>gdb</TT> command prompt:</P>
<!-- CODE SNIP //-->
<PRE>
(gdb) break 24
</PRE>
<!-- END CODE SNIP //-->
<P><TT>gdb</TT> should now print a response resembling the following:</P>
<!-- CODE SNIP //-->
<PRE>
Breakpoint 1 at 0x139: file greeting.c, line 24
(gdb)
</PRE>
<!-- END CODE SNIP //-->
<P>Now let’s run the program again by typing the <TT>run</TT> command. This command generates the following output:</P>
<!-- CODE SNIP //-->
<PRE>
Starting program: /root/greeting
The string is hello there
Breakpoint 1, my_print2 (string = 0xbfffdc4 “hello there”) at greeting.c
:24
24 string2[size-i]=string[i]
</PRE>
<!-- END CODE SNIP //-->
<P>We can see what is actually going wrong with the program by setting a watch which tells the value of the <TT>string2[size - i]</TT> variable expression.</P>
<P>To do this, type</P>
<!-- CODE SNIP //-->
<PRE>
(gdb) watch string2[size - i]
</PRE>
<!-- END CODE SNIP //-->
<P><TT>gdb</TT> returns the following acknowledgment:</P>
<!-- CODE SNIP //-->
<PRE>
Watchpoint 2: string2[size - i]
</PRE>
<!-- END CODE SNIP //-->
<P>The version of <TT>gdb</TT> included on the CD-ROM accompanying this book changes the prompt to <TT>Hardware Watchpoint</TT>, but this is simply a change in the naming convention used by <TT>gdb</TT>. Now we can step through the execution of the <TT>for</TT> loop using the <TT>next</TT> command:</P>
<!-- CODE SNIP //-->
<PRE>
(gdb) next
</PRE>
<!-- END CODE SNIP //-->
<P>After the first time through the loop, <TT>gdb</TT> tells us that <TT>string2[size - i]</TT> is <TT>’h’</TT> by displaying the following message on the screen:</P>
<!-- CODE SNIP //-->
<PRE>
Watchpoint 2, string2[size - i]
Old value = 0 ’\000’
New value = 104 ’h’
my_print2(string = 0xbfffdc4 “hello there”) at greeting.c:23
23 for (i=0; i<size; i++)
</PRE>
<!-- END CODE SNIP //-->
<P>This is the value that we expected. Stepping through the loop several more times reveals similar results. Everything appears to be functioning normally. When we get to the point where <TT>i=10</TT>, the value of the <TT>string2[size - i]</TT> expression is equal to <TT>’e,’</TT> the value of the <TT>size - i</TT> expression is equal to 1, and the program is at the last character that is to be copied over into the new string.</P>
<P>Step through the loop one more time and it’s clear that there is no value assigned to <TT>string2[0]</TT>, which is the first character of the string. Because the <TT>malloc</TT> function initializes the memory it assigns to null, the first character in <TT>string2</TT> is the null character. This explains why nothing is printed when we tried to print <TT>string2</TT>.</P>
<P>Now that we’ve found the problem, it should be quite easy to fix. We must write the code so that the first character going into <TT>string2</TT> is being put into <TT>string2</TT> at offset size - 1 instead of <TT>string2</TT> at offset size. This is because the size of <TT>string2</TT> is 12, but it starts numbering at offset zero. The characters in the string should start at offset 0 and go to offset 10, with offset 11 being reserved for the null character.</P>
<P>There are many ways to modify this code so that it will work. One way is to keep a separate size variable that is one smaller than the real size of the original string. This solution is shown in the following code:</P>
<!-- CODE //-->
<PRE>
#include <stdio.h>
main ()
{
char my_string[] = “hello there”;
my_print (my_string);
my_print2 (my_string);
}
my_print (char *string)
{
printf (“The string is %s\n”, string);
}
my_print2 (char *string)
{
char *string2;
int size, size2, i;
size = strlen (string);
size2 = size -1;
string2 = (char *) malloc (size + 1);
for (i = 0; i < size; i++)
string2[size2 - i] = string[i];
string2[size] = ’\0’;
printf (“The string printed backward is %s\n”, string2);
}
</PRE>
<!-- END CODE //-->
<H3><A NAME="Heading12"></A><FONT COLOR="#000077">Additional C Programming Tools</FONT></H3>
<P>The Slackware Linux distribution includes a number of C development tools that have not yet been described. This section describes many of these additional tools and their typical uses.
</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="468-472.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="474-478.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
</td>
</tr>
</table>
<!-- begin footer information -->
</body></html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?