Lessons learned from C Programming in Linux

Source: Internet
Author: User

The C programming time on the Linux platform for beginners is not long. This time, a business project needs to use the queue. I studied and compared the related products on the market, in general, it is not too complicated or the performance cannot meet the requirements. Therefore, I decided to write one by myself. This is the second time that C is fully implemented by itself. In the past, it was changed to the next open-source software. Generally, the performance of software under Linux is acceptable as long as it is developed by C. But ......, Write it by yourself. During the entire development process, there are too many tears and lessons to be learned. Record them here first. First, warn yourself and never commit again. Second, share it with useful people, if others skip the trap, try to avoid jumping again (as if I often do ?? Hey )!

1. memory leakage. This is an old problem. The developed MQ uses the TC server interface. with caution, almost every malloc object will be released as soon as possible, when writing to malloc, you are nervous. You must check whether all the malloc objects are free in this function. However, TC still killed me, because the get function with the value from TC was used, and the value returned by this function needs to be free by the developer. The result ......, Later, the error was discovered due to memory disorder. The cause of this problem is that you did not carefully read the TC documentation, cough, and cup.

2. pointer parameter: this problem can also be attributed to memory leakage. For the malloc variable, it must be set to null after free, so that we can program by judging whether the auto-increment is null. So in order to be simple and never forget the last null operation, I wrote this process as a function:

Void mem_free (void * PTR)

{

If (null! = PTR)

{

Free (PTR );

PTR = NULL;

}

}

If no problem is found, remove the PTR pointer and perform the null operation, but the problem arises. After executing the mem_free (buff) function for char * buff, the second running of mem_free (buff) was found to be null! = PTR is true. Why? This problem took me half a day. Later I checked the relevant books and found that when mem_free was used for the first time, free did clear the memory, but the bad thing was on PTR = NULL, note that at this time, PTR is only a copy pointing to the buff pointer, that is, the runtime temporal pointer can be understood as this PTR-> buff-> heap, free is because it does not change the PTR's direction, the value is free, so the value in heap is cleared, but PTR = NULL actually cut off the chain of PTR-> buff, the buff-> heap chain is not broken, so the buff actually points to the heap memory, although there is no useful data in the heap. But our intention is to disconnect the buff-> heap chain, so this function should be written to pass the second-level pointer:

Void mem_free (void ** PTR)

{

If (null! = * PTR)

{

Free (* PTR );

* PTR = NULL;

}

}

This problem can be summarized as follows: to change the pointer to the content, you do not need to pass the pointer address. To change the pointer to the content, you must pass the pointer address.

3. String (or character array, called string) Terminator. Many people do not understand the string Terminator, including the previous ones. Each string will end with a '\ 0' to show that the string is over. If the string is not completed manually, it will be automatically completed. In my experience, no matter when (declare char * buff = "I am Chinese. (Unless in this case), especially after strcpy or memcpy is executed, if you copy a string, you must manually complete it. Of course, if your memcpy is a binary memory, that sentence does not need to be completed.

4. Complete the memory. I am confused about this problem for 2 days. For example, there is a struct:

Typedef struct header_type

{

Char protocol;

Int state;

Int64_t bodylen;

} Header_t;

So does sizeof (header_t) and sizeof (char) + sizeof (INT) + sizeof (int64_t) have the same values? The answer is different. Don't say you have read it wrong. I'm sure it is different, at least it is different on my machine. The value of the former on my machine is 16, and the value of the latter is 13. The reason is that the memory is filled up. For C, memory completion is enabled when the applied memory is used. Some of the rules are fixed and some can be adjusted. For details, refer to CPU and compiler. On my machine, there are 2 ^ n rules, 1, 2, 4, 8, 16 ....... So after the length is 13, it is 16. This can be ignored if it is on the same machine, but if you want to pass this struct over the network, you cannot ignore it. There are two reasons: If you directly pass the variable of this struct, you need to consider the network byte order and memory size, this is too troublesome, give up, second: the work und for not considering cause 1 is to use char * to pass all of them. If you use sizeof (header_t) to apply for memory, the client receives the buff value as 16 bits, and the last three bits are useless, but the client does not know, therefore, memory confusion occurs. The solution is to apply for the char * buff memory, if the length is the real memory size, do not add the memory alignment gap. However, when you use malloc to apply for memory for headet_t objects, you must use sizeof (header_t) Because memory overflow occurs if sizeof is not used.

5. In Recv mode, whether it is in non-block mode or not, you must determine whether the request times out. I encountered this problem. After setting timeout, I did not judge the timeout. The client received the result returned by the server very unstable. It will be okay later (return within the timeout period ), it will be garbled again later. Later we found that the original Recv returned-1, and errno was set to 11. After this problem is solved, no data cannot be received.

6. byte Length: Due to Problem 5, I suspect the data transmission problem on the server, so I added the idea of printing the header_t buff, but this buff is a binary, it is not possible to print the binary directly. It can only be converted to hexadecimal format and then printed. Therefore, the followingCode;

Char header_buff [14];

Bin2hex (buff, 13, header_buff );

Log (header_buff );

ResultProgramEvery time you run it here, the system abort signal is triggered. The original file cannot be found. Later, I was instructed to find that the space requested by header_buff is incorrect. The binary length of header_t is 13, but each byte requires two bytes in hexadecimal notation. Therefore, 13 binary bytes require 26 bytes (a bit bypassing ), add the ending character of a string. Therefore, the request must contain 27 characters.

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.