Considerations when "pointer" as "function parameter" in C language

Source: Internet
Author: User
Considerations When "pointer" as "function parameter" in C language

In C, pointers are one of the most difficult points of knowledge to grasp, however, in the ordinary textbooks will be more detailed to explain the pointer, if you want to learn more in-depth C pointers in the detailed knowledge, recommend you can look at the "C and pointers", can also refer to "C Expert programming" or "C Traps and defects", These books on the C language is very in-depth, more than the basic teaching materials to speak more in-depth, you can see.


To get to the point, the main purpose of this article is to share with you a problem that I encountered when I was doing a project, that is, when the pointer as a function parameter, and want to use this function to allocate memory for the pointer when the problem arises, in the beginner's view, this may not be a problem, but also very natural in using, But this problem once caused me to do the project to have a very big bug, finally through some debugging means to find this problem, the following through the code and narrative to explain in detail.


We often encounter a function such as: allocating memory for a pointer and initializing the variable in its memory, a pointer that is generally a more complete structure pointer or other complex pointer, which is generally named: Mallocandinit (); The specific form will be given below, then we look at the first version of this function, we can first look at "version 1" there is no error.


Version 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define LEN 20

typedef struct 
person {
	char name[len];
	int age  ;
} person;

A return of 0 indicates a failure, and a return of 1 indicates success
int mallocandinit (person *pps)
{
	pPs = (person*) malloc (sizeof (person));

	if (NULL = pPs)
	{
		//memory allocation failure
		fprintf (stderr, "Malloc failed.\n");
		return 0;
	}

	Initialize
	pps->age = 0;
	strcpy (Pps->name, "");
	return 1;
}

void Main ()
{person
	*ptest = NULL;

	if (!mallocandinit (ptest))
	{
		fprintf (stderr, "error.\n");
		Exit (1);
	}

	There's going to be a mistake, you see why.
	printf ("The person's ' s name is%s, age is%d.\n", Ptest->name, ptest->age);

	if (ptest!= NULL)
	{free
		(ptest);
		Ptest = NULL;
	}
}



A person structure is defined in version 1, and there are a few things to explain:

1. The length of the array is generally used to define the macro to facilitate the subsequent project changes when the larger;

2. In the program, as far as possible some error control, that is, consider perfecting some, such as the above memory allocation is the success of the judgment and function calls whether to achieve the desired purpose of judgment;

3. Simplified definition using typedef;

4. Using NULL = PPS instead of PPS = NULL is a good programming habit, this is also in some interviews will be asked, the reason is because when the "= =" mistakenly written "=", the former direct compilation error, the latter can run, this hidden error is likely to cause the whole project confusion, This bug is sometimes difficult to find, so this habit is very important, the word is "judgment, the equal sign left to write a constant, equal to the right to write variables, to prevent less write an equal sign to bring serious bugs";

5. Finally, you must remember to use the pointer to free memory, otherwise there will be memory leaks and other issues.

Back to our theme, "Version 1" in a serious error, and difficult to find, compile without error, but the runtime will be an error, this situation suggests that you can step into the test to see if this pointer has been allocated to memory.

Why did it go wrong. Let's analyze, we need to figure out a problem: When pointer variables are passed as function parameters, when you need to modify the address value of the pointer variable itself, the equivalent of what we often say "value transfer", we all know that value transfer is not changing the value of the argument, a common example is the use of a function to exchange two variables of the value, If you have any questions about this, we suggest that you can see the basic teaching materials in the functional parameters and the relevant chapters, there will be detailed introduction. To say that, for a function argument that needs to modify the address value of the pointer, we are equivalent to "value delivery", so we call the Mallocandinit () function, and actually the pointer to the main function is the PPS or the unassigned memory pointer, This time we call the printf function to access the contents of this pointer is certainly wrong, because this is equivalent to accessing an unknown memory, which is a very dangerous operation. Should be brought to the attention.
In summary, it is a sentence that when you need to modify the address value of a pointer parameter in a function argument by using a function, this is equivalent to a pointer's value transfer operation, which is the same result as a normal variable value, and when you simply access or modify the contents of a pointer parameter in a function argument (for example, to modify the value of age in person) , this is equivalent to address delivery, and the argument results can be modified and passed out of the function.
Here are two solutions:
1. After allocating the memory to the pointer within the function, the assigned address is obtained by returning the pointer, see "Version 2";
2. Passing a two-level pointer to a function modifies the address value of a first-level pointer, which can be tricky, see version 3.

Version 2
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define LEN 20

typedef struct
person {
	char name[len];
	int age  ;
} person;

Return null indicates failure, and the return address indicates success
person* mallocandinit (person *pps)
{
	pPs = (person*) malloc (sizeof (person));

	if (NULL = pPs)
	{
		//memory allocation failure
		fprintf (stderr, "Malloc failed.\n");
		return NULL;
	}

	Initialize
	pps->age = 0;
	strcpy (Pps->name, "");
	return pPs;	Notice the change here ...
}

void Main ()
{person
	*ptest = NULL;

	Notice the change here ...
	if (!) ( Ptest = Mallocandinit (ptest)))
	{
		fprintf (stderr, "error.\n");
		Exit (1);
	}

	There will be no more errors
	printf ("The person's name is%s, the age is%d.\n", Ptest->name, ptest->age);

	Frees memory and restores
	if (ptest!= NULL)
	{free
		(ptest);
		Ptest = NULL;
	}
}

Version 3
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define LEN 20

typedef struct
person {
	char name[len];
	int age  ;
} person;

A return of 0 indicates failure, and 1 indicates success
int mallocandinit (person **ppps)
{
	*ppps = (person*) malloc (sizeof (person));

	if (NULL = = *ppps)
	{
		//memory allocation failure
		fprintf (stderr, "Malloc failed.\n");
		return 0;
	}

	Initialization
	(*ppps)->age = 0;
	strcpy ((*ppps)->name, "");
	return 1;	
}

void Main ()
{person
	*ptest   = NULL;
	Person **pptest = &pTest;	The secondary pointer points to the first level of pointers to be used ...

	//Here through the two-level pointer to the function of the internal allocation of a pointer to the memory, that is, the change of the first-level pointer address
	if (!mallocandinit (pptest))
	{
		fprintf (stderr, " Error.\n ");
		Exit (1);
	}

	There will be no more errors
	printf ("The person's name is%s, the age is%d.\n", Ptest->name, ptest->age);

	Frees memory and restores
	if (ptest!= NULL)
	{free
		(ptest);
		Ptest  = NULL;
		Pptest = NULL;
	}
}


In short, the C language pointer is really a headache, often because the pointer appears a variety of problems, so everyone should always be vigilant, encounter pointers to be highly careful.


The above program can be copied and pasted directly into VS, and can be run directly, after I have verified the issue, there is no understanding of the place to welcome you to leave a message, I see that will be in time to reply, this is the first write more, more careful, but also hope that we can savor, there is a need to exchange friends welcome message, Thank you.

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.