C + + returns traps for internal static members (GO)

Source: Internet
Author: User

There is always a problem in the process of developing C/D + + that brings us distress. The problem is that in-function and out-of-function code needs to interact with a piece of memory (for example, a function return string), a problem that bothers many developers. If your memory is allocated on the inside of a function stack, the memory will be released by the stack as the function returns, so you must return the memory that is valid outside of the function.

This is a problem that has plagued countless people. If you are not careful, you are likely to make a mistake on it. Of course there are a lot of solutions now, and if you are familiar with some standard libraries, you can see a lot of different ways to solve them. Broadly speaking, there are several:

1) Allocate memory on the heap through malloc or new within the function, and then return the memory (because the allocated memory on the heap is globally visible). The problem with this is a potential memory problem. Because, if the memory returned is not released, then it is the Leak. Or is released several times, which causes the crash of the program. These two problems are quite serious, so this design method is not recommended. (In some Windows APIs, when you call some APIs, you must also invoke some of his APIs to free up the memory)

2) Let the user pass in a piece of his own memory address, and in the function put the memory to be returned in this memory. This is a popular way to use it now. Many Windows API functions or standard C functions require you to pass in a buffer and the length of the buffer. This approach should be a common occurrence for us. The advantage of this approach is that the program outside the function to maintain the memory, relatively simple and intuitive. But the problem is that there's a little bit of trouble with it. But this approach minimizes the odds of making a mistake.

3) The third Way looks more alternative, he took advantage of the static characteristics, static stack memory once allocated, then this block of memory will not be released with the function return, and, it is globally visible (as long as you have the address of this memory). So, there are some functions that use the static feature, that is, the memory on the heap is not used, and the user is not required to pass in a buffer and its length. Thus, the use of their own functions are very beautiful, but also easy to use.

Here, I would like to have some discussion on the third method. Using static memory This method looks good, but it has traps that you can't imagine. Let's take an example with a case that actually happens.

  Example

A person with experience in socket programming must know that a function is called: Inet_ntoa, the function of the main function is to convert a digital IP address into a string, the definition of this function is such (note its return value):

  

Char *inet_ntoa (structin);

Obviously, this function does not allocate memory on the heap, and he does not let you pass the string of buffer entry, then he must use "return static char[" this method. Before we go on with our discussion, let's take a look at IP address-related knowledge, here's what the Inet_ntoa function needs to pass in: (You might be surprised that only one member struct is going to be in a struct?) This should be for the future extensibility of the program to consider)

C + + code
struct in_addr {  longint  s_addr;  }  

For IPV4, an IP address consists of four 8 bit bits, which are placed in the s_addr, high in the rear, for ease of network transmission. If you get an integer value of s_addr is: 3776385196. So, open your Windows calculator and see what the binary is? Let's right-to-left, 8-bit as a group (see below).

11100001 00010111 00010000 10101100

Then we turn each group into decimal, so we get: 225 23 16 172, so the IP address is 172.16.23.225.

Okay, here we are. We have a program that wants to record the source address and the address of the network packet, so we have the following code:

C + + code
struct in_addr src, des;  .........  .........   " Source IP Address <%s>/t destination IP address <%s>/n ", Inet_ntoa (SRC),   inet_ntoa (des));  

What kind of results will happen? You will find that the source IP address and destination IP address are exactly the same as recorded in the file. What's the problem? So you start debugging your program, and you find that src.s_addr and des.s_addr are fundamentally different (see below). But why is the source and destination of the output to the file the same? Is that a inet_ntoa bug?

C + + code
3776385196;    // corresponds to 172.16.23.225   1678184620;  // corresponds to 172.16.7.100  

The reason is Inet_ntoa () "smart" to the internal static char[] back, and our program is stepping on this trap. Let's examine the fprintf code. When we fprintf, the compiler computes Inet_ntoa (DES), so it returns the address of a string, and the program then asks for the Inet_ntoa (SRC) expression and gets the address of a string. The address of both strings is Inet_ntoa () in the static char[], obviously the same address, and the second time to seek the SRC IP, the value of the DES IP address content will be SRC IP coverage. So, the two expressions of the string memory are the same, at this time, the program will call fprintf the two strings (in fact, a) output to a file. So it's not surprising to get the same results.

Take a closer look at Inet_ntoa's man, and we can see this: the string is returned in a statically allocated buffer, which subsequent calls will OVERWR Ite. confirms our analysis.

  Summary

Let us all ask ourselves, do we use this method in the process of writing a program? This is a more dangerous and error-prone approach. This kind of trap is impossible to guard against. Think about it if you have such a program:

C + + code
if (strcmp (Inet_ntoa (IP1), Inet_ntoa (ip2)) = =0  ) {  ...  }  

I want to determine whether the two IP address is the same, but unexpectedly fell into the trap--let this conditional expression forever.

This tells us a few things:

1) Use caution in this way of design. There is a large pitfall in returning static memory inside a function.

2) If you must use this method. You have to be serious about telling everyone who uses this function, never use it more than once in an expression. Also, tell them not to copy the contents of the memory returned by the function, but simply to save the returned memory address or reference is useless. Otherwise, the consequences are not responsible.

3) C + + is a dangerous world, if you don't know what he's saying. Or temper the star to go.

Attached: A friend who has seen efftive C + + must know that there is one clause (item 23): Do not attempt to return a reference to an object. This article also discusses whether to return static variables inside the function. The result is a negative attitude.

Original address: http://www.jizhuomi.com/software/713.html

C + + returns traps for internal static members (GO)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.